home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 37
/
Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso
/
Aminet
/
game
/
misc
/
WormWars.lha
/
WormWars
/
Source
/
system.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-04-26
|
111KB
|
3,626 lines
/* $Filename: WormWars/Source/system.c $
* $VER: Worm Wars 5.61 for Amiga $
*
* © Copyright 2000 James R. Jacobs. Freely distributable.
* _
* // -=AMIGA=-
* //
* _ //
* \\ //
* \X/
#INCLUDES ---------------------------------------------------------------- */
#include "system.h" /* #includes everything else */
/* PROTOTYPES (Amiga-only) ----------------------------------------------- */
MODULE void freefx(void);
MODULE void helpabout(void);
MODULE void helploop(void);
MODULE void helpmanual(void);
MODULE void loadthefx(void);
MODULE void loadthemusic(void);
MODULE void parsewb(void);
MODULE void pausetimer(void);
MODULE void unpausetimer(void);
MODULE void dot(SBYTE x, SBYTE y);
MODULE void help(UBYTE type);
MODULE void preserve(SWORD x, SBYTE row, SBYTE image, UWORD amount);
MODULE void setpointer(SBYTE brush);
MODULE void toggle(SBYTE key);
MODULE void underline(SBYTE brush);
MODULE ABOOL beginfx(void);
MODULE UBYTE ReadJoystick(UWORD joynum);
MODULE SWORD xpixeltosquare(SWORD x);
MODULE SWORD ypixeltosquare(SWORD y);
/* EXTERNAL VARIABLES (owned by engine.c, imported by system.c) ----------- */
IMPORT struct Library* SysBase;
IMPORT ABOOL clearthem, modified;
IMPORT SBYTE a, board[MAXLEVELS + 1][FIELDX + 1][FIELDY + 1],
eachworm[4][2][9],
field[FIELDX + 1][FIELDY + 1],
level, levels, players,
startx[MAXLEVELS + 1], starty[MAXLEVELS + 1];
IMPORT SWORD secondsleft, secondsperlevel;
IMPORT ULONG delay, r;
IMPORT struct HiScoreStruct hiscore[HISCORES + 1];
IMPORT struct TeleportStruct teleport[MAXLEVELS + 1][4];
IMPORT struct WormStruct worm[4];
IMPORT TEXT pathname[81],
date[DATELENGTH + 1],
times[TIMELENGTH + 1];
/* MODULE VARIABLES (used only within system.c) --------------------------- */
AGLOBAL struct Library* TimerBase;
MODULE struct ASLBase* ASLBase = NULL;
MODULE struct DiskFontBase* DiskFontBase = NULL;
MODULE struct GadToolsBase* GadToolsBase = NULL;
MODULE struct GfxBase* GfxBase = NULL;
MODULE struct Library* IconBase = NULL;
MODULE struct IntuitionBase* IntuitionBase = NULL;
MODULE struct MEDPlayerBase* MEDPlayerBase = NULL;
MODULE struct UtilityBase* UtilityBase = NULL;
MODULE ABOOL eversent[4],
icons = TRUE,
ignore = FALSE,
iso = TRUE,
joy = FALSE,
sticky = FALSE;
MODULE SBYTE AudioClosed = TRUE,
brush = STONE,
Controller = GPCT_NOCONTROLLER,
JoyClosed = TRUE,
OldPri = 0,
TimerClosed = TRUE;
MODULE UBYTE fxable = 2,
mode = NULL;
musicable = 2;
MODULE ULONG fsize,
receipter[4] = {(ULONG) -1, (ULONG) -1, (ULONG) -1, (ULONG) -1};
MODULE UBYTE* fbase = NULL;
MODULE BPTR FilePtr = NULL;
MODULE APTR OldWindowPtr = NULL;
MODULE SWORD pixy;
MODULE struct InputEvent GameEvent;
MODULE struct TextAttr WormWars8 =
{ (STRPTR) "WormWars.font", 8, FS_NORMAL, FPF_DISKFONT | FPF_DESIGNED
}, Topaz8 =
{ (STRPTR) "topaz.font", 8, FS_NORMAL, FPF_ROMFONT | FPF_DESIGNED
};
MODULE struct Gadget *CheckboxGadgetPtr = NULL,
*CycleGadgetPtr[4] = {NULL, NULL, NULL, NULL},
*GListPtr = NULL,
*PrevGadgetPtr = NULL,
*StringGadgetPtr[5] = {NULL, NULL, NULL, NULL, NULL};
MODULE struct MsgPort *AudioPortPtr[4] = {NULL, NULL, NULL, NULL},
*JoyPortPtr = NULL,
*TimerPortPtr = NULL;
MODULE struct timeval *CurrentValPtr = NULL,
*PausedValPtr = NULL,
*StartValPtr = NULL;
MODULE struct Window *HelpWindowPtr = NULL,
*MainWindowPtr = NULL;
MODULE struct CIA* CIAPtr = (struct CIA *) 0xBFE001;
MODULE struct RDArgs* ArgsPtr = NULL;
MODULE struct FileRequester* ASLRqPtr = NULL;
MODULE struct IOAudio* AudioRqPtr[4] = {NULL, NULL, NULL, NULL};
MODULE struct TextFont* FontPtr = NULL;
MODULE struct IOStdReq* JoyRqPtr = NULL;
MODULE struct Menu* MenuPtr = NULL;
MODULE struct Process* ProcessPtr = NULL;
MODULE struct Screen* ScreenPtr = NULL;
MODULE struct MMD0* SongPtr = NULL;
MODULE struct timerequest* TimerRqPtr = NULL;
MODULE struct VisualInfo* VisualInfoPtr = NULL;
MODULE struct WBArg* WBArg = NULL;
MODULE struct WBStartup* WBMsg = NULL;
/* FUNCTIONS -------------------------------------------------------------- */
int main(int argc, char** argv)
{
BPTR OldDir;
SLONG i;
ABOOL success = FALSE;
SBYTE error = 0,
player, which;
TEXT saystring[SAYLIMIT + 1];
SWORD oldsecondsleft;
UWORD Pens[10] =
{ BLACK, /* DETAILPEN text in title bar */
WHITE, /* BLOCKPEN fill title bar */
WHITE, /* TEXTPEN regular text on BACKGROUNDPEN */
LIGHTGREY, /* SHINEPEN bright edge */
DARKGREY, /* SHADOWPEN dark edge */
PURPLE, /* FILLPEN filling active window borders
and selected gadgets */
BLACK, /* FILLTEXTPEN text rendered over FILLPEN */
BLACK, /* BACKGROUNDPEN background colour */
RED, /* HIGHLIGHTTEXTPEN highlighted text on BACKGROUNDPEN */
(UWORD) ~0 /* and used against BLOCKPEN in ASL save requesters */
};
SLONG args[10] = {0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L};
struct ColorSpec Colours[21] =
{ /* colour red green blue description */
{ 0, 0x0, 0x0, 0x0}, /* BLACK */
{ 1, 0xF, 0xF, 0xF}, /* WHITE */
{ 2, 0x4, 0x4, 0x4}, /* DARKGREY */
{ 3, 0x6, 0x6, 0x6}, /* MEDIUMGREY */
{ 4, 0xA, 0xA, 0xA}, /* LIGHTGREY */
{ 5, 0x0, 0x0, 0x0}, /* black */
{ 6, 0xA, 0x2, 0xA}, /* PURPLE */
{ 7, 0x8, 0x4, 0x2}, /* brown */
{ 8, 0x3, 0x9, 0x3}, /* DARKGREEN */
{ 9, 0x4, 0xE, 0x4}, /* light GREEN */
{ 10, 0xF, 0x1, 0x1}, /* DARKRED */
{ 11, 0xF, 0x5, 0x5}, /* light RED */
{ 12, 0x3, 0x3, 0xF}, /* DARKBLUE */
{ 13, 0x6, 0x6, 0xF}, /* light BLUE */
{ 14, 0xA, 0x8, 0x3}, /* DARKYELLOW */
{ 15, 0xC, 0xC, 0x2}, /* light YELLOW */
{ 16, 0x0, 0x0, 0x0}, /* pointer: transparent */
{ 17, 0xE, 0x4, 0x4}, /* pointer: fill */
{ 18, 0x3, 0x3, 0x3}, /* pointer: shadow */
{ 19, 0xC, 0xC, 0xC}, /* pointer: shine */
{ -1, NULL, NULL, NULL
} };
/* Start of program.
version embedding into executable */
if (0) /* that is, never */
say(VERSION, ANYTHING);
if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 37L)))
{ Write(Output(), OLDKICKSTART, strlen(OLDKICKSTART));
cleanexit(EXIT_FAILURE);
}
/* From this point onwards, we can be sure we have Kickstart 2.04+... */
for (i = 0; i <= SAMPLES; i++)
samp[i].base = NULL;
enginesetup();
ProcessPtr = (struct Process *) FindTask(NULL);
if (SysBase->lib_Version < 36L)
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Need exec.library V36+!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0L)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't open graphics.library!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(GadToolsBase = (struct GadToolsBase *) OpenLibrary("gadtools.library", 37L)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't open GadTools.library V37+!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(ASLBase = (struct ASLBase *) OpenLibrary("asl.library", 0L)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't open ASL.library!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(UtilityBase = (struct UtilityBase *) OpenLibrary("utility.library", 0L)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't open utility.library!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(IconBase = (struct Library *) OpenLibrary("icon.library", 0L)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't open icon.library!\0", 24);
cleanexit(EXIT_FAILURE);
}
/* argument parsing */
if (argc) /* started from CLI */
{ if (!(ArgsPtr = ReadArgs
( "-F=NOFX/S,-M=NOMUSIC/S,-I=NOICONS/S,-P=PRI/K/N,-O=OVERHEAD/S,"
"GREEN/K,RED/K,BLUE/K,YELLOW/K,FILE",
args,
NULL
)))
{ Printf
( "Usage: %s [-f=NOFX] [-m=NOMUSIC] [-i=NOICONS]\n"
"[-p=PRI <priority>] [-o=OVERHEAD] [GREEN=HUMAN|AMIGA|NONE]\n"
"[RED=HUMAN|AMIGA|NONE] [BLUE=HUMAN|AMIGA|NONE]\n"
"[YELLOW=HUMAN|AMIGA|NONE] [[FILE=]<fieldset>]\n",
argv[0]
);
cleanexit(EXIT_FAILURE);
}
if (args[0])
fxable = 3;
if (args[1])
musicable = 3;
if (args[2])
icons = FALSE;
if (args[3])
{ if (args[3] < -128 || args[3] > 5)
{ Printf("%s: Priority range is -128 to +5\n", argv[0]);
cleanexit(EXIT_FAILURE);
}
OldPri = SetTaskPri((struct Task *) ProcessPtr, args[3]);
}
if (args[4])
iso = FALSE;
if (args[5])
{ if (!stricmp(args[5], "HUMAN"))
worm[0].control = HUMAN;
elif (!stricmp(args[5], "AMIGA"))
worm[0].control = AMIGA;
elif (!stricmp(args[5], "NONE"))
worm[0].control = NONE;
else
{ Printf("%s: Green worm control must be HUMAN, AMIGA or NONE\n", argv[0]);
cleanexit(EXIT_FAILURE);
} }
if (args[6])
{ if (!stricmp(args[6], "HUMAN"))
worm[1].control = HUMAN;
elif (!stricmp(args[6], "AMIGA"))
worm[1].control = AMIGA;
elif (!stricmp(args[6], "NONE"))
worm[1].control = NONE;
else
{ Printf("%s: Red worm control must be HUMAN, AMIGA or NONE\n", argv[0]);
cleanexit(EXIT_FAILURE);
} }
if (args[7])
{ if (!stricmp(args[7], "HUMAN"))
worm[2].control = HUMAN;
elif (!stricmp(args[7], "AMIGA"))
worm[2].control = AMIGA;
elif (!stricmp(args[7], "NONE"))
worm[2].control = NONE;
else
{ Printf("%s: Blue worm control must be HUMAN, AMIGA or NONE\n", argv[0]);
cleanexit(EXIT_FAILURE);
} }
if (args[8])
{ if (!stricmp(args[8], "HUMAN"))
worm[3].control = HUMAN;
elif (!stricmp(args[8], "AMIGA"))
worm[3].control = AMIGA;
elif (!stricmp(args[8], "NONE"))
worm[3].control = NONE;
else
{ Printf("%s: Yellow worm control must be HUMAN, AMIGA or NONE\n", argv[0]);
cleanexit(EXIT_FAILURE);
} }
if (args[9])
strcpy(pathname, args[9]);
}
else /* started from WB */
{ WBMsg = (struct WBStartup *) argv;
WBArg = WBMsg->sm_ArgList; /* head of the arg list */
for (i = 0;
i < WBMsg->sm_NumArgs;
i++, WBArg++)
{ if (WBArg->wa_Lock)
{ /* something that does not support locks */
parsewb();
}
else
{ /* locks supported, change to the proper directory */
OldDir = CurrentDir(WBArg->wa_Lock);
parsewb();
CurrentDir(OldDir);
}
if (i == 1)
strcpy(pathname, WBArg->wa_Name);
} }
if (!(DiskFontBase = (struct DiskFontBase *) OpenLibrary("diskfont.library", 0L)))
error = 1;
if
( (!(StartValPtr = (struct timeval *) AllocMem(sizeof(struct timeval), MEMF_PUBLIC | MEMF_CLEAR)))
|| (!(CurrentValPtr = (struct timeval *) AllocMem(sizeof(struct timeval), MEMF_PUBLIC | MEMF_CLEAR)))
|| (!(PausedValPtr = (struct timeval *) AllocMem(sizeof(struct timeval), MEMF_PUBLIC | MEMF_CLEAR)))
)
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't allocate timer value structure!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(TimerPortPtr = (struct MsgPort *) CreateMsgPort()))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't allocate timer message port!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(TimerRqPtr = (struct timerequest *) CreateIORequest(TimerPortPtr, sizeof(struct timerequest))))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't create timer I/O request!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (TimerClosed = OpenDevice(TIMERNAME, UNIT_VBLANK, TimerRqPtr, 0))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't open timer.device!\0", 24);
cleanexit(EXIT_FAILURE);
}
TimerBase = (struct Library *) TimerRqPtr->tr_node.io_Device;
/* PREPARE DISPLAY -----------------------------------------------
font and screen */
if ((!error) && (FontPtr = (struct TextFont *) OpenDiskFont(&WormWars8)))
{ /* loaded WormWars.font
It would be possible to pass SA_Interleaved on any OS version,
provided that it was ignored by 2.04-2.1. */
if (IntuitionBase->LibNode.lib_Version >= 39) /* if we're running on OS3.0+ */
{ ScreenPtr = (struct Screen *) OpenScreenTags
( NULL,
SA_Width, 640,
SA_Height, 256,
SA_Depth, DEPTH,
SA_DisplayID, HIRES_KEY | PAL_MONITOR_ID,
SA_Title, TITLEBAR,
SA_Colors, Colours,
SA_Font, &WormWars8,
SA_Pens, Pens,
SA_Interleaved, TRUE,
TAG_DONE
);
} else
{ ScreenPtr = (struct Screen *) OpenScreenTags
( NULL,
SA_Width, 640,
SA_Height, 256,
SA_Depth, DEPTH,
SA_DisplayID, HIRES_KEY | PAL_MONITOR_ID,
SA_Title, TITLEBAR,
SA_Colors, Colours,
SA_Font, &WormWars8,
SA_Pens, Pens,
TAG_DONE
);
}
if (!ScreenPtr)
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't open screen!\0", 24);
cleanexit(EXIT_FAILURE);
} }
else
{ if (!error)
error = 2;
if (IntuitionBase->LibNode.lib_Version >= 39) /* if we're running on OS3.0+ */
{ ScreenPtr = (struct Screen *) OpenScreenTags
( NULL,
SA_Width, 640,
SA_Height, 256,
SA_Depth, DEPTH,
SA_DisplayID, HIRES_KEY | PAL_MONITOR_ID,
SA_Title, TITLEBAR,
SA_Colors, Colours,
SA_Font, &Topaz8,
SA_Pens, Pens,
SA_Interleaved, TRUE,
TAG_DONE
);
} else
{ ScreenPtr = (struct Screen *) OpenScreenTags
( NULL,
SA_Width, 640,
SA_Height, 256,
SA_Depth, DEPTH,
SA_DisplayID, HIRES_KEY | PAL_MONITOR_ID,
SA_Title, TITLEBAR,
SA_Colors, Colours,
SA_Font, &Topaz8,
SA_Pens, Pens,
TAG_DONE
);
}
if (!ScreenPtr)
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't open screen nor font!\0", 24);
cleanexit(EXIT_FAILURE);
} }
/* For some reason, we lose 2 memory chunks: 264 bytes and 10 bytes. This
seems perhaps to not be our fault. */
/* GadTools */
if (!(CycleGadget.ng_VisualInfo = StringGadget.ng_VisualInfo = CheckboxGadget.ng_VisualInfo = VisualInfoPtr = (APTR) GetVisualInfo(ScreenPtr, TAG_DONE)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't get GadTools visual info!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(MenuPtr = (struct Menu *) CreateMenus(NewMenu, TAG_DONE)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't create menus!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(LayoutMenus(MenuPtr, VisualInfoPtr, TAG_DONE)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't lay out menus!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!(PrevGadgetPtr = (struct Gadget *) CreateContext(&GListPtr)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't create GadTools context!\0", 24);
cleanexit(EXIT_FAILURE);
}
for (player = 0; player <= 3; player++)
{ CycleGadget.ng_TopEdge = 184 + (player * (FONTX + 8));
CycleGadget.ng_GadgetText = CycleText[player];
CycleGadgetPtr[player] = PrevGadgetPtr = (struct Gadget *) CreateGadget
( CYCLE_KIND,
PrevGadgetPtr,
&CycleGadget,
GTCY_Labels, CycleOptions[player],
GTCY_Active, worm[player].control,
GT_Underscore, '_',
GA_Disabled, TRUE,
TAG_DONE
);
}
CheckboxGadgetPtr = PrevGadgetPtr = (struct Gadget *) CreateGadget
( CHECKBOX_KIND,
PrevGadgetPtr,
&CheckboxGadget,
GTCB_Checked, iso,
GT_Underscore, '_',
GA_Disabled, TRUE,
TAG_DONE
);
/* main window */
if (!(MainWindowPtr = (struct Window *) OpenWindowTags(NULL,
WA_Top, 11,
WA_Width, SCREENXPIXEL,
WA_Height, SCREENYPIXEL,
WA_IDCMP, IDCMP_RAWKEY | IDCMP_MOUSEBUTTONS | IDCMP_CLOSEWINDOW | IDCMP_ACTIVEWINDOW | IDCMP_MENUPICK | IDCMP_MENUVERIFY | CYCLEIDCMP | STRINGIDCMP | CHECKBOXIDCMP | IDCMP_REFRESHWINDOW | IDCMP_INTUITICKS,
WA_Gadgets, GListPtr,
WA_CustomScreen, ScreenPtr,
WA_Borderless, TRUE,
WA_Activate, TRUE,
WA_SmartRefresh, TRUE,
WA_RptQueue, 16,
TAG_DONE)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't open main window!\0", 24);
cleanexit(EXIT_FAILURE);
}
/* redirection of AmigaDOS system requesters */
OldWindowPtr = ProcessPtr->pr_WindowPtr;
ProcessPtr->pr_WindowPtr = (APTR) MainWindowPtr;
if (!(ASLRqPtr = AllocAslRequestTags(ASL_FileRequest, ASL_Pattern, PATTERN, ASL_Window, MainWindowPtr, TAG_DONE)))
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't create ASL request!\0", 24);
cleanexit(EXIT_FAILURE);
}
/* String gadgets: first the window is opened with the cycle and
checkbox gadgets.
It is necessary not to display the string gadgets yet, so the
gadgets are then created and added to the gadget list. You will note
there is no command given to render them as yet. When the attributes
are modified at highscore time, the applicable gadget is refreshed
then. */
for (which = 0; which <= HISCORES; which++)
{ StringGadget.ng_TopEdge = 104 + (which * HISCOREDISTANCE);
StringGadgetPtr[which] = PrevGadgetPtr = (struct Gadget *) CreateGadget(STRING_KIND, PrevGadgetPtr, &StringGadget, GTST_MaxChars, NAMELENGTH, STRINGA_ReplaceMode, TRUE, GA_Disabled, TRUE, TAG_DONE);
}
if (!PrevGadgetPtr)
{ DisplayAlert(AT_Recovery, "\0\20\20Worm Wars: Can't create GadTools gadgets!\0", 24);
cleanexit(EXIT_FAILURE);
}
if (!icons)
NewMenu[CREATEICONS].nm_Flags &= ~CHECKED;
if (error == 1)
{ say("Can't open diskfont.library!", RED);
anykey(TRUE);
} else if (error == 2)
{ say("Can't open WormWars.font!", RED);
anykey(TRUE);
}
if (!(JoyPortPtr = (struct MsgPort *) CreateMsgPort()))
{ say("Can't create joystick message port!", BLUE);
anykey(TRUE);
} else if (!(JoyRqPtr = (struct IOStdReq *) CreateIORequest(JoyPortPtr, sizeof(struct IOStdReq))))
{ say("Can't create joystick I/O request!", BLUE);
anykey(TRUE);
} else if (JoyClosed = OpenDevice("gameport.device", 1, JoyRqPtr, 0))
{ say("Can't open gameport.device!", BLUE);
anykey(TRUE);
} else
{ Forbid();
JoyRqPtr->io_Command = GPD_ASKCTYPE;
JoyRqPtr->io_Length = 1;
JoyRqPtr->io_Flags = IOF_QUICK;
JoyRqPtr->io_Data = (APTR) &Controller;
DoIO(JoyRqPtr);
if (Controller == GPCT_NOCONTROLLER)
{ Controller = GPCT_ABSJOYSTICK;
JoyRqPtr->io_Command = GPD_SETCTYPE;
JoyRqPtr->io_Length = 1;
JoyRqPtr->io_Data = (APTR) &Controller;
DoIO(JoyRqPtr);
success = TRUE;
}
Permit();
/* Note that say(), anykey() calls must be outside the
Forbid()/Permit() pair. */
if (success)
{ JoyRqPtr->io_Command = GPD_SETTRIGGER;
JoyRqPtr->io_Data = (APTR) &Trigger;
JoyRqPtr->io_Length = sizeof(struct GamePortTrigger);
DoIO(JoyRqPtr);
sendreadrequest();
joy = TRUE;
} else
{ say("Gameport already in use!", BLUE);
anykey(TRUE);
} }
/* By default, preload music and sound effects at startup.
musicable and fxable values are:
0: tried and failed
1: tried and succeeded
2: untried, will load at startup
3: untried, will load when needed */
if (musicable == 2)
loadthemusic();
if (fxable == 2)
loadthefx();
if (fxable == 1)
toggle(F);
else if (musicable == 1)
toggle(M);
strcpy(saystring, "Loading ");
strcat(saystring, pathname);
strcat(saystring, "...");
say(saystring, WHITE);
if (loadfields(pathname))
{ strcpy(saystring, "Can't open ");
strcat(saystring, pathname);
strcat(saystring, "!");
say(saystring, RED);
newfields();
anykey(TRUE);
}
while (1)
{ titlescreen();
/* MAIN GAME LOOP ------------------------------------------------- */
while (a == PLAYGAME)
{ r++;
oldsecondsleft = secondsleft;
GetSysTime(CurrentValPtr);
SubTime(CurrentValPtr, StartValPtr);
secondsleft = secondsperlevel - CurrentValPtr->tv_secs;
if (secondsleft != oldsecondsleft)
timeloop();
TimerRqPtr->tr_node.io_Command = TR_ADDREQUEST;
TimerRqPtr->tr_time.tv_secs = 0;
TimerRqPtr->tr_time.tv_micro = delay;
SendIO(TimerRqPtr);
gameloop();
if (CheckIO(TimerRqPtr))
draw(CLOCKICON, ICONY, CLOCK);
else draw(CLOCKICON, ICONY, BLACKENED);
WaitIO(TimerRqPtr);
}
say("Title Screen", WHITE);
}
}
/* SUPPORT FUNCTIONS ----------------------------------------------------- */
/* NAME anykey -- wait for a user press
SYNOPSIS anykey(ABOOL);
FUNCTION Waits for a user response. Optional automatic timeout.
INPUTS timeout - timeout?
RESULTS FALSE if user presses Escape, TRUE otherwise.
FILE system.c */
ABOOL anykey(ABOOL timeout)
{ ABOOL done = FALSE;
SBYTE count = 0;
UWORD code, qual;
ULONG class;
struct IntuiMessage* MsgPtr;
clearkybd();
Forbid();
MainWindowPtr->Flags |= WFLG_RMBTRAP;
Permit();
while (!done)
{ if (joy && GetMsg(JoyPortPtr))
{ if (GameEvent.ie_Code == IECODE_LBUTTON)
done = TRUE;
sendreadrequest();
}
if (joy)
{ Wait((1L << MainWindowPtr->UserPort->mp_SigBit) | (1L << JoyPortPtr->mp_SigBit));
while (GetMsg(JoyPortPtr))
{ if (GameEvent.ie_Code == IECODE_LBUTTON)
done = TRUE;
sendreadrequest();
} }
else Wait(1L << MainWindowPtr->UserPort->mp_SigBit);
while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
{ class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
GT_ReplyIMsg(MsgPtr);
switch(class)
{
case IDCMP_RAWKEY:
if ((!(qual & IEQUALIFIER_REPEAT)) && code < KEYUP && (code < FIRSTQUALIFIER || code > LASTQUALIFIER))
{ done = TRUE;
if (code == M)
toggle(M);
else if (code == F)
toggle(F);
else if (code == ESCAPE)
{ if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
if (verify())
cleanexit(EXIT_SUCCESS);
else
{ Forbid();
MainWindowPtr->Flags &= ~WFLG_RMBTRAP;
Permit();
return FALSE;
} } }
break;
case IDCMP_CLOSEWINDOW:
cleanexit(EXIT_SUCCESS);
break;
case IDCMP_ACTIVEWINDOW:
ignore = TRUE;
break;
case IDCMP_MOUSEBUTTONS:
if ((code == SELECTDOWN || code == MENUDOWN) && !(qual & IEQUALIFIER_REPEAT))
if (ignore)
ignore = FALSE;
else done = TRUE;
break;
case IDCMP_INTUITICKS:
if (timeout && ++count > PATIENCE)
done = TRUE;
break;
default:
break;
} } }
Forbid();
MainWindowPtr->Flags &= ~WFLG_RMBTRAP;
Permit();
return TRUE;
}
void celebrate(void)
{ ABOOL done = FALSE;
ULONG class;
UWORD code, qual;
struct IntuiMessage* MsgPtr;
UBYTE player;
for (player = 0; player <= 3; player++)
if (worm[player].control != NONE && worm[player].score >= worm[player].hiscore)
worm[player].hiscore = worm[player].score;
waitasec();
clearkybd();
while (!done)
{ while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
{ class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
GT_ReplyIMsg(MsgPtr);
switch (class)
{
case IDCMP_RAWKEY:
if (code == ESCAPE)
{ if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (verify())
cleanexit(EXIT_SUCCESS);
} else
done = TRUE;
}
else if (code == RETURN || code == ENTER || code == SPACEBAR)
done = TRUE;
else if (code == M)
toggle(M);
else if (code == F)
toggle(F);
break;
case IDCMP_MOUSEBUTTONS:
if (code == SELECTDOWN && !(qual & IEQUALIFIER_REPEAT))
if (ignore)
ignore = FALSE;
else done = TRUE;
break;
case IDCMP_ACTIVEWINDOW:
ignore = TRUE;
break;
case IDCMP_CLOSEWINDOW:
cleanexit(EXIT_SUCCESS);
break;
default:
break;
} }
if (joy && GetMsg(JoyPortPtr))
{ if (GameEvent.ie_Code == IECODE_LBUTTON)
done = TRUE;
sendreadrequest();
}
SetRGB4(&ScreenPtr->ViewPort, 17, rand() % 16, rand() % 16, rand() % 16);
draw(rand() % (FIELDX + 1), rand() % (FIELDY + 1), rand() % LASTOBJECT);
}
SetRGB4(&ScreenPtr->ViewPort, 17, 14, 4, 4);
a = GAMEOVER;
}
AGLOBAL void cleanexit(SLONG rc)
{ SBYTE i;
if (TimerRqPtr && (!CheckIO(TimerRqPtr)))
{ AbortIO(TimerRqPtr);
WaitIO(TimerRqPtr); }
freefx();
for (i = 0; i <= SAMPLES; i++)
if (samp[i].base)
FreeMem(samp[i].base, samp[i].size);
if (mode == MUSIC) StopPlayer();
if (SongPtr) UnLoadModule(SongPtr);
if (MEDPlayerBase) { FreePlayer();
CloseLibrary(MEDPlayerBase); }
if (joy) { AbortIO(JoyRqPtr);
WaitIO(JoyRqPtr); }
if (Controller != GPCT_NOCONTROLLER)
{ Forbid();
Controller = GPCT_NOCONTROLLER;
JoyRqPtr->io_Command = GPD_SETCTYPE;
JoyRqPtr->io_Length = 1;
JoyRqPtr->io_Data = (APTR) &Controller;
DoIO(JoyRqPtr);
Permit(); }
if (!JoyClosed) CloseDevice(JoyRqPtr);
if (JoyRqPtr) DeleteIORequest(JoyRqPtr);
if (JoyPortPtr) DeleteMsgPort(JoyPortPtr);
if (ASLRqPtr) FreeAslRequest(ASLRqPtr);
if (OldWindowPtr) ProcessPtr->pr_WindowPtr = OldWindowPtr;
if (MainWindowPtr) { clearkybd();
ClearMenuStrip(MainWindowPtr);
CloseWindow(MainWindowPtr); }
if (GListPtr) FreeGadgets(GListPtr);
if (MenuPtr) FreeMenus(MenuPtr);
if (VisualInfoPtr) FreeVisualInfo(VisualInfoPtr);
if (ScreenPtr) CloseScreen(ScreenPtr);
if (FontPtr) CloseFont(FontPtr);
if (!TimerClosed) CloseDevice(TimerRqPtr);
if (TimerRqPtr) DeleteIORequest(TimerRqPtr);
if (TimerPortPtr) DeleteMsgPort(TimerPortPtr);
if (PausedValPtr) FreeMem(PausedValPtr, sizeof(struct timeval));
if (CurrentValPtr) FreeMem(CurrentValPtr, sizeof(struct timeval));
if (StartValPtr) FreeMem(StartValPtr, sizeof(struct timeval));
if (DiskFontBase) CloseLibrary(DiskFontBase);
if (UtilityBase) CloseLibrary(UtilityBase);
if (ASLBase) CloseLibrary(ASLBase);
if (GadToolsBase) CloseLibrary(GadToolsBase);
if (GfxBase) CloseLibrary(GfxBase);
if (IconBase) CloseLibrary(IconBase);
if (IntuitionBase) { OpenWorkBench();
CloseLibrary(IntuitionBase); }
SetTaskPri((struct Task *) ProcessPtr, OldPri);
if (ArgsPtr) FreeArgs(ArgsPtr);
exit(rc); /* End of program. */
}
void clearjoystick(void)
{ if (joy)
while (GetMsg(JoyPortPtr))
sendreadrequest();
}
void clearkybd(void)
{ struct IntuiMessage* MsgPtr;
while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
GT_ReplyIMsg(MsgPtr);
}
void draw(SBYTE x, SBYTE y, SBYTE image)
{ SWORD pixx;
/* Isometric methodology:
read the colour of the pixel, then set the colour in the image
to the same value.
So if, for the top left pixel, we read colour 10 (= $A or %1010),
we have to clear the relevant bits in plane 0 and 2, and set them
in planes 1 and 3.
plane 0 (least significant bit)
1234567890123456 pixels for top row (y = 0)
1234567890123456 pixels for next row (y = 1)
: : :
plane 1
: : :
01234567890
0..#########
1..#########
2.#########.
3.#########.
4#########..
5#########..
Image is effectively 9*6, but requires an 11*6 bitmap.
31
268421
731000521
689942152631
8426842684268421
**.......**..... */
if (a == PLAYGAME && iso)
{ IsoImage.ImageData = IsoImageData[image];
pixx = (x * ISOSQUAREX) + 20 + ((FIELDY - y) * 3);
pixy = (y * ISOSQUAREY) + STARTYPIXEL;
preserve(pixx, 0, image, 32768);
preserve(pixx, 1, image, 32768);
preserve(pixx, 2, image, 32768);
preserve(pixx, 3, image, 32768);
preserve(pixx + 1, 0, image, 16384);
preserve(pixx + 1, 1, image, 16384);
preserve(pixx + 9, 4, image, 64);
preserve(pixx + 9, 5, image, 64);
preserve(pixx + 10, 2, image, 32);
preserve(pixx + 10, 3, image, 32);
preserve(pixx + 10, 4, image, 32);
preserve(pixx + 10, 5, image, 32);
DrawImage
( MainWindowPtr->RPort,
&IsoImage,
pixx,
pixy
);
} else
{ /* blit square */
Image.ImageData = ImageData[image];
DrawImage
( MainWindowPtr->RPort,
&Image,
STARTXPIXEL + (SQUAREX * x),
STARTYPIXEL + (SQUAREY * y)
);
} }
MODULE void preserve(SWORD x, SBYTE row, SBYTE image, UWORD amount)
{ LONG colour;
/* x = image top-left corner coordinate on destination screen.
row = y-row of the image.
image = image number
amount = value of the bit to be set/cleared. */
colour = ReadPixel
( MainWindowPtr->RPort,
x,
pixy + row
);
if (colour & 8)
IsoImageData[image][row + 18] |= amount;
else IsoImageData[image][row + 18] &= ~amount;
if (colour & 4)
IsoImageData[image][row + 12] |= amount;
else IsoImageData[image][row + 12] &= ~amount;
if (colour & 2)
IsoImageData[image][row + 6] |= amount;
else IsoImageData[image][row + 6] &= ~amount;
if (colour & 1)
IsoImageData[image][row] |= amount;
else IsoImageData[image][row] &= ~amount;
}
void effect(SBYTE index)
{ SBYTE i;
SBYTE ok = -1;
ULONG oldestreceipt = (ULONG) -1L;
PERSIST ULONG nextreceipt = 1L;
/* oldestreceipt = temporary variable for ascertaining oldest
sound still playing.
nextreceipt = next unused receipt number (monotonically incrementing). */
if (mode == FX)
{ for (i = 0; i <= 3; i++)
{ /* decide on a channel */
if (ok == -1)
{ if (!eversent[i])
ok = i;
else if (CheckIO(AudioRqPtr[i]))
{ WaitIO(AudioRqPtr[i]);
ok = i;
} } }
if (ok == -1)
{ for (i = 0; i <= 3; i++)
if (receipter[i] < oldestreceipt)
{ ok = i;
oldestreceipt = receipter[i];
}
AbortIO(AudioRqPtr[ok]);
WaitIO(AudioRqPtr[ok]);
}
eversent[ok] = TRUE;
AudioRqPtr[ok]->ioa_Cycles = 1;
AudioRqPtr[ok]->ioa_Request.io_Command = CMD_WRITE;
AudioRqPtr[ok]->ioa_Request.io_Flags = ADIOF_PERVOL;
AudioRqPtr[ok]->ioa_Request.io_Unit = (1 << ok);
AudioRqPtr[ok]->ioa_Volume = samp[index].volume;
AudioRqPtr[ok]->ioa_Period = (UWORD) samp[index].speed;
AudioRqPtr[ok]->ioa_Request.io_Message.mn_ReplyPort
= AudioPortPtr[ok];
AudioRqPtr[ok]->ioa_Data = (UBYTE *) samp[index].base;
AudioRqPtr[ok]->ioa_Length = samp[index].length[samp[index].bank];
BeginIO(AudioRqPtr[ok]);
receipter[ok] = nextreceipt;
} }
void fieldedit(void)
{ UBYTE oldbrush = ANYTHING, stamp;
SBYTE deltax = 0, deltay = 0, lastx, lasty, pointerx, pointery, which, x, y;
UWORD code, qual;
ULONG class;
struct IntuiMessage* MsgPtr;
ABOOL leftdown = FALSE, rightdown = FALSE, timer = FALSE;
struct MenuItem* ItemPtr;
PERSIST SBYTE clipboard[FIELDX + 1][FIELDY + 1];
PERSIST ABOOL clipboarded = FALSE;
say("Field Editor", WHITE);
setpointer(brush);
if (level > levels)
level = levels;
OnMenu(MainWindowPtr, FULLMENUNUM(MN_EDIT, NOITEM, NOSUB));
if (!clipboarded)
OffMenu(MainWindowPtr, FULLMENUNUM(MN_EDIT, IN_PASTE, NOSUB));
/* draw pseudo-gadgets */
clearscreen();
for (which = 0; which <= 8; which++)
DrawBevelBox(MainWindowPtr->RPort, STARTXPIXEL - 5 - (SQUAREX * 3), 40 + STARTYPIXEL + (which * SQUAREY * 3), SQUAREX + 9, SQUAREY + 4, GT_VisualInfo, VisualInfoPtr);
SetAPen(MainWindowPtr->RPort, WHITE);
Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + ( GOLDGADGET * SQUAREY));
Text(MainWindowPtr->RPort, "F1:", 3);
Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + (SILVERGADGET * SQUAREY));
Text(MainWindowPtr->RPort, "F2:", 3);
Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + ( EMPTYGADGET * SQUAREY));
Text(MainWindowPtr->RPort, "F3:", 3);
Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + ( WOODGADGET * SQUAREY));
Text(MainWindowPtr->RPort, "F4:", 3);
Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + ( STONEGADGET * SQUAREY));
Text(MainWindowPtr->RPort, "F5:", 3);
Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + ( METALGADGET * SQUAREY));
Text(MainWindowPtr->RPort, "F6:", 3);
Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + ( ONEGADGET * SQUAREY));
Text(MainWindowPtr->RPort, "F7:", 3);
Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + ( TWOGADGET * SQUAREY));
Text(MainWindowPtr->RPort, "F8:", 3);
Move(MainWindowPtr->RPort, STARTXPIXEL - (FONTX * 8), STARTYPIXEL + 5 + ( STARTGADGET * SQUAREY));
Text(MainWindowPtr->RPort, "F9:", 3);
draw(GADGETX, GOLDGADGET, GOLD);
draw(GADGETX, SILVERGADGET, SILVER);
draw(GADGETX, EMPTYGADGET, EMPTY);
draw(GADGETX, WOODGADGET, WOOD);
draw(GADGETX, STONEGADGET, STONE);
draw(GADGETX, METALGADGET, METAL);
draw(GADGETX, ONEGADGET, ONE);
draw(GADGETX, TWOGADGET, TWO);
draw(GADGETX, STARTGADGET, START);
SetAPen(MainWindowPtr->RPort, BLACK);
RectFill
( MainWindowPtr->RPort,
STARTXPIXEL - SQUAREX - 1,
UNDERLINEOFFSET - 1,
STARTXPIXEL - SQUAREX + 3,
UNDERLINEOFFSET + 4 + (SQUAREY * 25)
);
underline(brush);
turborender();
saylevel(WHITE);
clearkybd();
x = lastx = startx[level];
y = lasty = starty[level];
while (a == FIELDEDIT)
{ stamp = NOSQUARE;
if (MsgPtr = (struct IntuiMessage *) GetMsg(MainWindowPtr->UserPort))
{ class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
if (class == IDCMP_MENUVERIFY && MsgPtr->MouseX >= STARTXPIXEL && MsgPtr->MouseX <= ENDXPIXEL && MsgPtr->MouseY >= STARTYPIXEL && MsgPtr->MouseY <= ENDYPIXEL)
{ MsgPtr->Code = MENUCANCEL;
oldbrush = brush;
brush = EMPTY;
rightdown = TRUE;
}
ReplyMsg(MsgPtr);
switch (class)
{
case IDCMP_MENUPICK:
while (code != MENUNULL)
{ ItemPtr = ItemAddress(MenuPtr, code);
switch (MENUNUM(code))
{
case MN_PROJECT:
switch (ITEMNUM(code))
{
case IN_NEW:
effect(FXFILENEW);
newfields();
say("New done.", WHITE);
break;
case IN_OPEN:
effect(FXFILEOPEN);
fileopen(FALSE);
break;
case IN_REVERT:
fileopen(TRUE);
break;
case IN_SAVE:
effect(FXFILESAVE);
if (modified)
{ clearhiscores();
modified = FALSE;
}
filesaveas(FALSE);
break;
case IN_SAVEAS:
effect(FXFILESAVEAS);
if (modified)
{ clearhiscores();
modified = FALSE;
}
filesaveas(TRUE);
break;
case IN_QUIT:
if (verify())
cleanexit(EXIT_SUCCESS);
break;
default:
break;
}
break;
case MN_EDIT:
switch (ITEMNUM(code))
{
case IN_CUT:
effect(FXEDITCUT);
for (x = 0; x <= FIELDX; x++)
for (y = 0; y <= FIELDY; y++)
clipboard[x][y] = board[level][x][y];
leveldelete();
clipboarded = TRUE;
modified = TRUE;
OnMenu(MainWindowPtr, FULLMENUNUM(MN_EDIT, IN_PASTE, NOSUB));
break;
case IN_COPY:
effect(FXEDITCOPY);
for (x = 0; x <= FIELDX; x++)
for (y = 0; y <= FIELDY; y++)
clipboard[x][y] = board[level][x][y];
clipboarded = TRUE;
OnMenu(MainWindowPtr, FULLMENUNUM(MN_EDIT, IN_PASTE, NOSUB));
break;
case IN_PASTE:
effect(FXEDITPASTE);
for (x = 0; x <= FIELDX; x++)
for (y = 0; y <= FIELDY; y++)
board[level][x][y] = clipboard[x][y];
turborender();
modified = TRUE;
break;
case IN_ERASE:
levelerase();
break;
case IN_INSERT:
levelinsert();
break;
case IN_DELETE:
effect(FXLEVELDELETE);
leveldelete();
break;
case IN_APPEND:
levelappend();
break;
default:
break;
}
break;
case MN_SETTINGS:
switch(ITEMNUM(code))
{
case IN_CREATEICONS:
if (ItemPtr->Flags & CHECKED)
icons = TRUE;
else icons = FALSE;
break;
default:
break;
}
break;
case MN_HELP:
switch(ITEMNUM(code))
{
case IN_CREATURES:
help(ORB);
break;
case IN_OBJECTS:
help(AFFIXER);
break;
case IN_MANUAL:
helpmanual();
break;
case IN_ABOUT:
helpabout();
break;
default:
break;
}
break;
default:
break;
}
code = ItemPtr->NextSelect;
}
break;
case IDCMP_RAWKEY:
lastx = x;
lasty = y;
switch(code)
{
case DELETE:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
level = 1;
else if (--level < 0)
level = levels;
saylevel(WHITE);
turborender();
}
break;
case HELP:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
level = levels;
else if (++level > levels)
level = 0;
saylevel(WHITE);
turborender();
}
break;
case M:
if (!(qual & IEQUALIFIER_REPEAT))
toggle(M);
break;
case F:
if (!(qual & IEQUALIFIER_REPEAT))
toggle(F);
break;
case ESCAPE:
if (!(qual & IEQUALIFIER_REPEAT))
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (verify())
cleanexit(EXIT_SUCCESS);
} else a = GAMEOVER;
break;
case SPACEBAR:
case RETURN:
case ENTER:
if (!(qual & IEQUALIFIER_REPEAT))
a = GAMEOVER;
break;
case NUMERICOPEN:
effect(FXCLICK);
setpointer(NORMAL);
underline(-1);
if (brush-- == 0 || brush > LASTOBJECT)
brush = LASTOBJECT;
stamp = brush;
break;
case NUMERICCLOSE:
effect(FXCLICK);
setpointer(NORMAL);
underline(-1);
if (++brush > LASTOBJECT)
brush = 0;
stamp = brush;
break;
break;
case C:
effect(FXPENGUINDEATH); /* interesting */
x = FIELDX / 2;
y = FIELDY / 2;
break;
case ALPHAONE:
effect(FXCLICK);
stamp = GOLD;
break;
case ALPHATWO:
effect(FXCLICK);
stamp = SILVER;
break;
case ALPHATHREE:
effect(FXCLICK);
stamp = EMPTY;
break;
case ALPHAFOUR:
effect(FXCLICK);
stamp = WOOD;
break;
case ALPHAFIVE:
effect(FXCLICK);
stamp = STONE;
break;
case ALPHASIX:
effect(FXCLICK);
stamp = METAL;
break;
case ALPHASEVEN:
effect(FXCLICK);
stamp = ONE;
break;
case ALPHAEIGHT:
effect(FXCLICK);
stamp = TWO;
break;
case ALPHANINE:
effect(FXCLICK);
stamp = START;
break;
case F1:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
fillfield(GOLD);
else setbrush(GOLD);
}
break;
case F2:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
fillfield(SILVER);
else setbrush(SILVER);
}
break;
case F3:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
fillfield(EMPTY);
else setbrush(EMPTY);
}
break;
case F4:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
fillfield(WOOD);
else setbrush(WOOD);
}
break;
case F5:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
fillfield(STONE);
else setbrush(STONE);
}
break;
case F6:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
fillfield(METAL);
else setbrush(METAL);
}
break;
case F7:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
setbrush(ONE);
}
break;
case F8:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
setbrush(TWO);
}
break;
case F9:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
setbrush(START);
}
break;
case NUMERICZERO:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
if (!sticky)
{ sticky = TRUE;
stamp = brush;
} else
{ sticky = FALSE;
dot(x, y);
} }
break;
case NUMERICDOT:
if (!(qual & IEQUALIFIER_REPEAT))
{ effect(FXCLICK);
stamp = brush;
}
break;
case NUMERICFOUR:
case LEFT:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
x = 0;
else if ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
x = xwrap(x - ALTJUMP);
else
x = xwrap(x - 1);
if (sticky)
stamp = brush;
break;
case NUMERICSIX:
case RIGHT:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
x = FIELDX;
else if ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
x = xwrap(x + ALTJUMP);
else
x = xwrap(x + 1);
if (sticky)
stamp = brush;
break;
case NUMERICEIGHT:
case UP:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
y = 0;
else if ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
y = ywrap(y - ALTJUMP);
else
y = ywrap(y - 1);
if (sticky)
stamp = brush;
break;
case NUMERICFIVE:
case NUMERICTWO:
case DOWN:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
y = FIELDY;
else if ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
y = ywrap(y + ALTJUMP);
else
y = ywrap(y + 1);
if (sticky)
stamp = brush;
break;
case NUMERICSEVEN:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
{ x = 0;
y = 0;
} else if ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
{ x = xwrap(x - ALTJUMP);
y = ywrap(y - ALTJUMP);
} else
{ x = xwrap(x - 1);
y = ywrap(y - 1);
}
if (sticky)
stamp = brush;
break;
case NUMERICNINE:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
{ x = FIELDX;
y = 0;
} else if ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
{ x = xwrap(x + ALTJUMP);
y = ywrap(y - ALTJUMP);
} else
{ x = xwrap(x + 1);
y = ywrap(y - 1);
}
if (sticky)
stamp = brush;
break;
case NUMERICONE:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
{ x = 0;
y = FIELDY;
} else if ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
{ x = xwrap(x - ALTJUMP);
y = ywrap(y + ALTJUMP);
} else
{ x = xwrap(x - 1);
y = ywrap(y + 1);
}
if (sticky)
stamp = brush;
break;
case NUMERICTHREE:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT) || (qual & IEQUALIFIER_CONTROL))
{ x = FIELDX;
y = FIELDY;
} else if ((qual & IEQUALIFIER_LALT) || (qual & IEQUALIFIER_RALT))
{ x = xwrap(x + ALTJUMP);
y = ywrap(y + ALTJUMP);
} else
{ x = xwrap(x + 1);
y = ywrap(y + 1);
}
if (sticky)
stamp = brush;
break;
default:
break;
}
if (x != lastx || y != lasty)
{ updatesquare(lastx, lasty);
if (stamp > LASTOBJECT)
dot(x, y);
}
break;
case IDCMP_MOUSEBUTTONS:
updatesquare(x, y);
switch (code)
{
case SELECTUP:
leftdown = FALSE;
break;
case SELECTDOWN:
effect(FXCLICK);
leftdown = TRUE;
break;
case MENUUP:
rightdown = FALSE;
brush = oldbrush;
oldbrush = ANYTHING;
break;
default:
/* MENUDOWN */
break;
}
break;
case IDCMP_CLOSEWINDOW:
cleanexit(EXIT_SUCCESS);
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(MainWindowPtr);
GT_EndRefresh(MainWindowPtr, TRUE);
break;
default:
/* IDCMP_MENUVERIFY, IDCMP_INTUITICKS, IDCMP_ACTIVEWINDOW */
break;
} }
else if (joy)
{ if (GetMsg(JoyPortPtr))
{ if (GameEvent.ie_Code == IECODE_LBUTTON)
stamp = brush;
deltax = (SBYTE) GameEvent.ie_position.ie_xy.ie_x;
deltay = (SBYTE) GameEvent.ie_position.ie_xy.ie_y;
if (GameEvent.ie_Qualifier == IEQUALIFIER_LEFTBUTTON)
stamp = brush;
sendreadrequest();
}
if (deltax || deltay)
{ if (!timer)
{ TimerRqPtr->tr_node.io_Command = TR_ADDREQUEST;
TimerRqPtr->tr_time.tv_secs = 0;
TimerRqPtr->tr_time.tv_micro = JOYDELAY;
SendIO(TimerRqPtr);
timer = TRUE;
} else if (CheckIO(TimerRqPtr))
{ lastx = x;
lasty = y;
x = xwrap(x + deltax);
y = ywrap(y + deltay);
updatesquare(lastx, lasty);
dot(x, y);
timer = FALSE;
} } }
if (leftdown || rightdown)
{ pointerx = xpixeltosquare(MainWindowPtr->MouseX);
pointery = ypixeltosquare(MainWindowPtr->MouseY);
if (valid(pointerx, pointery))
{ x = pointerx;
y = pointery;
stamp = brush;
updatesquare(lastx, lasty);
}
else if (leftdown && pointerx == GADGETX &&
(pointery == GOLDGADGET
|| pointery == SILVERGADGET
|| pointery == EMPTYGADGET
|| pointery == WOODGADGET
|| pointery == STONEGADGET
|| pointery == METALGADGET
|| pointery == ONEGADGET
|| pointery == TWOGADGET
|| pointery == STARTGADGET))
{ switch (pointery)
{
case GOLDGADGET:
setbrush(GOLD);
break;
case SILVERGADGET:
setbrush(SILVER);
break;
case EMPTYGADGET:
setbrush(EMPTY);
break;
case WOODGADGET:
setbrush(WOOD);
break;
case STONEGADGET:
setbrush(STONE);
break;
case METALGADGET:
setbrush(METAL);
break;
case ONEGADGET:
setbrush(ONE);
break;
case TWOGADGET:
setbrush(TWO);
break;
case STARTGADGET:
setbrush(START);
break;
default:
break;
} } }
if (stamp != NOSQUARE)
{ if (stamp == START && board[level][x][y] != TELEPORT)
{ if (x != startx[level] || y != starty[level])
{ draw(startx[level], starty[level], EMPTY);
board[level][startx[level]][starty[level]] = EMPTY;
draw(x, y, START);
startx[level] = x;
starty[level] = y;
modified = TRUE;
clearthem = TRUE;
} }
else if (x != startx[level] || y != starty[level])
{ if (stamp == ONE || stamp == TWO)
{ if (teleport[level][partner(stamp - ONE)].alive == FALSE || x != teleport[level][partner(stamp - ONE)].x || y != teleport[level][partner(stamp - ONE)].y)
{ if (teleport[level][stamp - ONE].alive == TRUE)
{ draw(teleport[level][stamp - ONE].x, teleport[level][stamp - ONE].y, EMPTY);
board[level][teleport[level][stamp - ONE].x][teleport[level][stamp - ONE].y] = EMPTY;
} else
teleport[level][stamp - ONE].alive = TRUE;
board[level][x][y] = TELEPORT;
draw(x, y, stamp);
teleport[level][stamp - ONE].x = x;
teleport[level][stamp - ONE].y = y;
modified = TRUE;
clearthem = TRUE;
} }
else
{ if (board[level][x][y] == TELEPORT)
if (teleport[level][0].alive == TRUE && x == teleport[level][0].x && y == teleport[level][0].y)
teleport[level][0].alive = FALSE;
else teleport[level][1].alive = FALSE;
draw(x, y, stamp);
board[level][x][y] = stamp;
if (sticky)
dot(x, y);
modified = TRUE;
clearthem = TRUE;
} } } }
/* exit to title screen */
OffMenu(MainWindowPtr, FULLMENUNUM(MN_EDIT, NOITEM, NOSUB));
if (timer)
{ AbortIO(TimerRqPtr);
WaitIO(TimerRqPtr);
}
if (oldbrush != ANYTHING)
brush = oldbrush;
setpointer(NORMAL);
if (clearthem)
clearhiscores();
matchteleports();
}
MODULE void help(UBYTE type)
{ TEXT title[10];
SWORD x, y;
UBYTE i;
effect(FXAMIGAN);
if (type == ORB)
{ strcpy(title, "Creatures");
x = 112;
y = 118;
} else
{ strcpy(title, "Objects");
x = 640;
y = 160;
}
if (!(HelpWindowPtr = (struct Window *) OpenWindowTags(NULL,
WA_Left, (SCREENXPIXEL / 2) - (x / 2),
WA_Top, (SCREENYPIXEL / 2) - (y / 2),
WA_Width, x,
WA_Height, y,
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_RAWKEY,
WA_Title, title,
WA_Gadgets, NULL,
WA_CustomScreen, ScreenPtr,
WA_DragBar, TRUE,
WA_CloseGadget, TRUE,
WA_NoCareRefresh, TRUE,
WA_Activate, TRUE,
TAG_DONE)))
{ say("Can't open help window!", RED);
anykey(TRUE);
} else
{ SetAPen(HelpWindowPtr->RPort, WHITE);
if (type == ORB)
{ for (i = 0; i <= CREATUREHELPS; i++)
{ Image.ImageData = ImageData[creaturehelp[i].image];
DrawImage
( HelpWindowPtr->RPort,
&Image,
10,
15 + (i * 10)
);
Move(HelpWindowPtr->RPort, 26, 20 + (i * 10));
Text(HelpWindowPtr->RPort, creaturehelp[i].desc, strlen(creaturehelp[i].desc));
} }
else /* assumes (type == AFFIXER) */
{ for (i = 0; i <= LASTOBJECT; i++)
{ Image.ImageData = ImageData[i];
if (i <= LASTOBJECT / 2)
{ Move(HelpWindowPtr->RPort, 26, 20 + (i * 10));
DrawImage
( HelpWindowPtr->RPort,
&Image,
10,
15 + (i * 10)
);
} else
{ Move(HelpWindowPtr->RPort, 354, 10 + ((i - (LASTOBJECT / 2)) * 10));
DrawImage
( HelpWindowPtr->RPort,
&Image,
338,
5 + ((i - (LASTOBJECT / 2)) * 10)
);
}
Text(HelpWindowPtr->RPort, objectdesc[i], strlen(objectdesc[i]));
} }
helploop();
} }
MODULE void helpmanual(void)
{ /* Consider for 5.7: Asynchronous execution of MultiView using
dos.library/SystemTagList(). And if we passed a lock to our PROGDIR: to
MultiView, even better. */
if (!Execute("SYS:Utilities/MultiView WormWars.guide", NULL, NULL))
DisplayBeep(ScreenPtr);
else ScreenToFront(ScreenPtr);
}
MODULE void helpabout(void)
{ SBYTE line;
SLONG projectval;
TEXT projectstring[6], ks[5] = " ", wb[5] = " ";
ULONG ksval = SysBase->lib_Version,
wbval = IconBase->lib_Version;
effect(FXAMIGAN);
if (!(HelpWindowPtr = (struct Window *) OpenWindowTags(NULL,
WA_Left, (SCREENXPIXEL / 2) - (ABOUTXPIXEL / 2),
WA_Top, (SCREENYPIXEL / 2) - (ABOUTYPIXEL / 2),
WA_Width, ABOUTXPIXEL,
WA_Height, ABOUTYPIXEL,
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_RAWKEY,
WA_Title, "About Worm Wars",
WA_Gadgets, NULL,
WA_CustomScreen, ScreenPtr,
WA_DragBar, TRUE,
WA_CloseGadget, TRUE,
WA_NoCareRefresh, TRUE,
WA_Activate, TRUE,
TAG_DONE)))
{ say("Can't open About... window!", RED);
anykey(TRUE);
} else
{ /* calculate project size */
projectval =
11 /* header */
+ ((HISCORES + 1) * (9 + NAMELENGTH + DATELENGTH + TIMELENGTH))
/* high scores */
+ ((levels + 1) * (7 + ((FIELDX + 1) * (FIELDY + 1)))) /* level data */
+ levels
+ strlen(VERSION)
+ 1;
switch(ksval)
{
case 37:
strcpy(ks, "2.04");
break;
case 38:
strcpy(ks, "2.1 ");
break;
case 39:
strcpy(ks, "3.0 ");
break;
case 40:
strcpy(ks, "3.1 ");
break;
default:
strcpy(ks, "4.0+");
break;
}
switch(wbval)
{
case 37:
strcpy(wb, "2.04");
break;
case 38:
strcpy(wb, "2.1 ");
break;
case 39:
strcpy(wb, "3.0 ");
break;
case 40:
case 41:
case 42:
case 43:
strcpy(wb, "3.1 ");
break;
case 44:
strcpy(wb, "3.5 ");
break;
default:
strcpy(wb, "4.0+");
break;
}
SetAPen(HelpWindowPtr->RPort, worm[rand() % 4].colour);
RectFill(HelpWindowPtr->RPort, 8, 13, ABOUTXPIXEL - 11, ABOUTYPIXEL - 6);
SetAPen(HelpWindowPtr->RPort, ABOUTSHADOW);
Move(HelpWindowPtr->RPort, 7, ABOUTYPIXEL - 5);
Draw(HelpWindowPtr->RPort, 7, 12);
Draw(HelpWindowPtr->RPort, ABOUTXPIXEL - 10, 12);
SetAPen(HelpWindowPtr->RPort, ABOUTSHINE);
Draw(HelpWindowPtr->RPort, ABOUTXPIXEL - 10, ABOUTYPIXEL - 5);
Draw(HelpWindowPtr->RPort, 8, ABOUTYPIXEL - 5);
SetAPen(HelpWindowPtr->RPort, BLACK);
SetDrMd(HelpWindowPtr->RPort, JAM1);
for (line = 0; line <= ABOUTLINES; line++)
{ Move(HelpWindowPtr->RPort, about[line].x, about[line].y);
Text(HelpWindowPtr->RPort, about[line].text, (SBYTE) strlen(about[line].text));
}
stcl_d(projectstring, projectval);
align(projectstring, 5, ' ');
Move(HelpWindowPtr->RPort, PROJECTX, PROJECTY);
Text(HelpWindowPtr->RPort, projectstring, 5);
Move(HelpWindowPtr->RPort, KICKSTARTX, KICKSTARTY);
Text(HelpWindowPtr->RPort, ks, 4);
Move(HelpWindowPtr->RPort, WORKBENCHX, WORKBENCHY);
Text(HelpWindowPtr->RPort, wb, 4);
DrawBevelBox(HelpWindowPtr->RPort, 18, 21, 47, 22, GT_VisualInfo, VisualInfoPtr);
DrawImage(HelpWindowPtr->RPort, &About, 19, 22);
helploop();
} }
MODULE void helploop(void)
{ ABOOL done = FALSE;
UWORD code, qual;
ULONG class;
struct IntuiMessage* MsgPtr;
while(!done)
{ Wait(1L << HelpWindowPtr->UserPort->mp_SigBit);
while (MsgPtr = (struct IntuiMessage *) GetMsg(HelpWindowPtr->UserPort))
{ class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
ReplyMsg(MsgPtr);
switch(class)
{
case IDCMP_CLOSEWINDOW:
done = TRUE;
break;
case IDCMP_RAWKEY:
if (code == SPACEBAR || code == RETURN || code == ENTER || code == HELP)
done = TRUE;
else if (code == ESCAPE)
if (qual & IEQUALIFIER_LSHIFT || qual & IEQUALIFIER_RSHIFT)
{ if (verify())
{ CloseWindow(HelpWindowPtr);
cleanexit(EXIT_SUCCESS);
} }
else done = TRUE;
break;
default:
break;
} } }
CloseWindow(HelpWindowPtr);
clearkybd();
}
AGLOBAL void fileopen(ABOOL revert)
{ TEXT temp1[81] = {"Opened "}, temp2[3], newpathname[255];
strcpy(newpathname, pathname);
if (revert || (AslRequestTags(ASLRqPtr, ASL_Hail, "Open Fieldset", ASL_FuncFlags, FILF_PATGAD, TAG_DONE) && *(ASLRqPtr->rf_File)))
{ if (!revert)
{ strcpy(newpathname, ASLRqPtr->rf_Dir);
AddPart(newpathname, ASLRqPtr->rf_File, 254);
}
if (!loadfields(newpathname))
{ strcpy(pathname, newpathname);
strcat(temp1, pathname);
strcat(temp1, " (");
stci_d(temp2, levels);
strcat(temp1, temp2);
strcat(temp1, " levels).");
say(temp1, WHITE);
if (a == FIELDEDIT)
turborender();
else hiscores();
} else
{ strcpy(temp1, "Couldn't open ");
strcat(temp1, newpathname);
strcat(temp1, "!");
say(temp1, WHITE);
} }
if (a == GAMEOVER)
anykey(TRUE);
}
AGLOBAL void filesaveas(ABOOL flag)
{ ABOOL cont = TRUE;
TEXT newpathname[255], temp1[SAYLIMIT + 1], temp2[3];
struct DiskObject* InfoHandle;
/* flag is TRUE for 'save as...', FALSE for 'save'. */
strcpy(newpathname, pathname);
if (flag)
if (AslRequestTags(ASLRqPtr, ASL_Hail, "Save Fieldset", ASL_FuncFlags, FILF_PATGAD | FILF_SAVE, TAG_DONE) && *(ASLRqPtr->rf_File) != 0)
{ strcpy(newpathname, ASLRqPtr->rf_Dir);
AddPart(newpathname, ASLRqPtr->rf_File, 254);
} else cont = FALSE;
if (cont)
{ strcpy(temp1, "Saving ");
strcat(temp1, newpathname);
strcat(temp1, "...");
say(temp1, WHITE);
if (savefields(newpathname))
{ strcpy(pathname, newpathname);
if (icons)
{ InfoHandle = GetDiskObjectNew(DEFAULTSET);
InfoHandle->do_CurrentX = NO_ICON_POSITION;
InfoHandle->do_CurrentY = NO_ICON_POSITION;
if (!PutDiskObject(pathname, InfoHandle))
{ say("Couldn't write .info file!", RED);
anykey(TRUE);
} }
strcpy(temp1, "Saved ");
strcat(temp1, pathname);
strcat(temp1, " (");
stci_d(temp2, levels);
strcat(temp1, temp2);
strcat(temp1, " levels).");
} else
{ strcpy(temp1, "Couldn't save ");
strcat(temp1, newpathname);
strcat(temp1, "!");
}
say(temp1, WHITE);
if (a == GAMEOVER)
anykey(TRUE);
} }
MODULE void freefx(void)
{ SBYTE i;
stopfx();
if (!AudioClosed)
{ CloseDevice((struct IORequest *) AudioRqPtr[0]);
AudioClosed = TRUE;
}
for (i = 0; i <= 3; i++)
{ if (AudioRqPtr[i])
{ DeleteIORequest(AudioRqPtr[i]);
AudioRqPtr[i] = NULL;
}
if (AudioPortPtr[i])
{ DeleteMsgPort(AudioPortPtr[i]);
AudioPortPtr[i] = NULL;
} }
if (fbase)
{ FreeMem(fbase, fsize);
fbase = NULL;
}
if (FilePtr)
{ Close(FilePtr);
FilePtr = NULL;
} }
void gameinput(void)
{ ABOOL done;
UWORD code, qual;
ULONG class;
struct IntuiMessage* MsgPtr;
SBYTE keyplayer;
UBYTE which;
for (which = 0; which <= NUMKEYS; which++)
key[which].down = FALSE;
/* keyboard */
while (MsgPtr = (struct IntuiMessage *) GetMsg(MainWindowPtr->UserPort))
{ class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
ReplyMsg(MsgPtr);
if (class == IDCMP_RAWKEY && (!(qual & IEQUALIFIER_REPEAT)) && code < KEYUP)
{ switch(code) {
case M:
toggle(M);
break;
case F:
toggle(F);
break;
case P:
clearkybd();
say("Paused...press P to unpause", WHITE);
pausetimer();
done = FALSE;
while (!done)
{ Wait(1L << MainWindowPtr->UserPort->mp_SigBit);
while (MsgPtr = (struct IntuiMessage *) GetMsg(MainWindowPtr->UserPort))
{ class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
ReplyMsg(MsgPtr);
if (class == IDCMP_RAWKEY && (!(qual & IEQUALIFIER_REPEAT)))
{ if (code == ESCAPE)
{ if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (verify())
cleanexit(EXIT_SUCCESS);
} else
{ a = GAMEOVER;
done = TRUE;
worm[0].lives = worm[1].lives = worm[2].lives = worm[3].lives = 0;
} }
else if (code == M)
toggle(M);
else if (code == F)
toggle(F);
else if (code == P)
{ say("Unpaused", WHITE);
done = TRUE;
} } } }
unpausetimer();
break;
case ESCAPE:
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (verify())
cleanexit(EXIT_SUCCESS);
} else
{ a = GAMEOVER;
worm[0].lives = worm[1].lives = worm[2].lives = worm[3].lives = 0;
}
break;
default:
for (which = 0; which <= NUMKEYS; which++)
if (code == key[which].scancode)
key[which].down = TRUE;
break;
} }
else if (class == IDCMP_CLOSEWINDOW)
cleanexit(EXIT_SUCCESS);
else if (class == IDCMP_REFRESHWINDOW)
{ GT_BeginRefresh(MainWindowPtr);
GT_EndRefresh(MainWindowPtr, TRUE);
} }
/* Received but ignored: IDCMP_ACTIVEWINDOW, IDCMP_MOUSEBUTTONS and
IDCMP_INTUITICKS. */
for (which = 0; which <= NUMKEYS; which++)
{ if (key[which].down)
{ if (key[which].special == ONEHUMAN)
{ if (worm[0].control == HUMAN && worm[1].control != HUMAN)
wormqueue(0, key[which].deltax, key[which].deltay);
else if (worm[0].control != HUMAN && worm[1].control == HUMAN)
wormqueue(1, key[which].deltax, key[which].deltay);
} else if (key[which].special == MOVE || key[which].special == AMMO)
{ if (worm[key[which].player].control == HUMAN)
keyplayer = key[which].player;
else if (key[which].player == 1 && worm[0].control == HUMAN && worm[1].control != HUMAN)
keyplayer = 0;
else if (key[which].player == 0 && worm[1].control == HUMAN && worm[0].control != HUMAN)
keyplayer = 1;
else keyplayer = -1;
if (keyplayer != -1)
wormqueue(keyplayer, key[which].deltax, key[which].deltay);
} else if (worm[1].lives) /* assumes key[which].special == TRAINER */
train(key[which].scancode);
} }
/* joystick */
if (worm[2].control == HUMAN)
while (GetMsg(JoyPortPtr))
{ if (GameEvent.ie_position.ie_xy.ie_x != 0 || GameEvent.ie_position.ie_xy.ie_y != 0)
wormqueue(2, GameEvent.ie_position.ie_xy.ie_x, GameEvent.ie_position.ie_xy.ie_y);
if (GameEvent.ie_Code == IECODE_LBUTTON)
wormqueue(2, 0, 0);
sendreadrequest();
} }
void hiscores(void)
{ SBYTE which;
TEXT tempstring[NAMELENGTH + 1];
/* render hiscores
#################################################### # = shadow
# # # # # # % % = shine
# # # # # # %
# # # # # # %
# # # # # # %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
SetDrMd(MainWindowPtr->RPort, JAM1);
for (which = 0; which <= HISCORES; which++)
{ if (hiscore[which].player == -1)
SetAPen(MainWindowPtr->RPort, LIGHTGREY);
else SetAPen(MainWindowPtr->RPort, worm[hiscore[which].player].colour);
RectFill(MainWindowPtr->RPort, 104, 105 + which * HISCOREDISTANCE, 536, 114 + which * HISCOREDISTANCE);
if (hiscore[which].player == 0)
SetAPen(MainWindowPtr->RPort, DARKGREEN);
else if (hiscore[which].player == 1)
SetAPen(MainWindowPtr->RPort, DARKRED);
else if (hiscore[which].player == 2)
SetAPen(MainWindowPtr->RPort, DARKBLUE);
else if (hiscore[which].player == 3)
SetAPen(MainWindowPtr->RPort, DARKYELLOW);
else SetAPen(MainWindowPtr->RPort, DARKGREY);
Move(MainWindowPtr->RPort, 103, 115 + which * HISCOREDISTANCE);
Draw(MainWindowPtr->RPort, 103, 104 + which * HISCOREDISTANCE);
Draw(MainWindowPtr->RPort, 537, 104 + which * HISCOREDISTANCE);
if (hiscore[which].player != -1)
{ /* divider bars */
Move(MainWindowPtr->RPort, 182 - 55, 104 + which * HISCOREDISTANCE);
Draw(MainWindowPtr->RPort, 182 - 55, 114 + which * HISCOREDISTANCE);
Move(MainWindowPtr->RPort, 254 - 55, 104 + which * HISCOREDISTANCE);
Draw(MainWindowPtr->RPort, 254 - 55, 114 + which * HISCOREDISTANCE);
Move(MainWindowPtr->RPort, 290 - 55, 104 + which * HISCOREDISTANCE);
Draw(MainWindowPtr->RPort, 290 - 55, 114 + which * HISCOREDISTANCE);
Move(MainWindowPtr->RPort, 416, 104 + which * HISCOREDISTANCE);
Draw(MainWindowPtr->RPort, 416, 114 + which * HISCOREDISTANCE);
Move(MainWindowPtr->RPort, 464, 104 + which * HISCOREDISTANCE);
Draw(MainWindowPtr->RPort, 464, 114 + which * HISCOREDISTANCE);
}
SetAPen(MainWindowPtr->RPort, WHITE);
Move(MainWindowPtr->RPort, 159 - 55, 115 + which * HISCOREDISTANCE);
Draw(MainWindowPtr->RPort, 482 + 55, 115 + which * HISCOREDISTANCE);
Draw(MainWindowPtr->RPort, 482 + 55, 105 + which * HISCOREDISTANCE);
SetAPen(MainWindowPtr->RPort, BLACK);
if (hiscore[which].player != -1)
{ stci_d(tempstring, which + 1);
tempstring[1] = '.';
Move(MainWindowPtr->RPort, 161 - 55, 112 + which * HISCOREDISTANCE);
Text(MainWindowPtr->RPort, tempstring, 2);
stci_d(tempstring, hiscore[which].score);
align(tempstring, 7, ' ');
Move(MainWindowPtr->RPort, 193 - 55, 112 + which * HISCOREDISTANCE);
Text(MainWindowPtr->RPort, tempstring, 7);
if (hiscore[which].level == -1)
strcpy(tempstring, "All");
else
{ stci_d(tempstring, hiscore[which].level);
align(tempstring, 3, ' ');
}
Move(MainWindowPtr->RPort, 206, 112 + which * HISCOREDISTANCE);
Text(MainWindowPtr->RPort, tempstring, 3);
Move(MainWindowPtr->RPort, 241, 112 + which * HISCOREDISTANCE);
Text(MainWindowPtr->RPort, hiscore[which].name, strlen(hiscore[which].name));
Move(MainWindowPtr->RPort, 418, 112 + which * HISCOREDISTANCE);
Text(MainWindowPtr->RPort, hiscore[which].time, strlen(hiscore[which].time));
Move(MainWindowPtr->RPort, 466, 112 + which * HISCOREDISTANCE);
Text(MainWindowPtr->RPort, hiscore[which].date, strlen(hiscore[which].date));
} }
SetDrMd(MainWindowPtr->RPort, JAM2);
}
void hiscorenames(void)
{
ULONG class;
ABOOL done;
SBYTE which;
struct IntuiMessage* MsgPtr;
for (which = 0; which <= HISCORES; which++)
if (hiscore[which].fresh)
{ GT_SetGadgetAttrs(StringGadgetPtr[which], MainWindowPtr, NULL, GA_Disabled, FALSE, GTST_String, worm[hiscore[which].player].name, TAG_DONE);
ActivateGadget(StringGadgetPtr[which], MainWindowPtr, NULL);
done = FALSE;
while (!done)
{ while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
{ class = MsgPtr->Class;
GT_ReplyIMsg(MsgPtr);
if (class == IDCMP_GADGETUP)
done = TRUE;
else if (class == IDCMP_MOUSEBUTTONS)
ActivateGadget(StringGadgetPtr[which], MainWindowPtr, NULL);
else if (class == IDCMP_REFRESHWINDOW)
{ GT_BeginRefresh(MainWindowPtr);
GT_EndRefresh(MainWindowPtr, TRUE);
} } }
GT_SetGadgetAttrs(StringGadgetPtr[which], MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
effect(FXHISCORE);
strcpy(hiscore[which].name, ((struct StringInfo *) (StringGadgetPtr[which]->SpecialInfo))->Buffer);
if (hiscore[which].name[0] >= 97 && hiscore[which].name[0] <= 123)
hiscore[which].name[0] -= 32;
strcpy(worm[hiscore[which].player].name, hiscore[which].name);
hiscore[which].fresh = FALSE;
hiscores();
} }
MODULE ABOOL beginfx(void)
{ SBYTE i;
PERSIST UBYTE chan[] = {15};
for (i = 0; i <= 3; i++)
{ eversent[i] = FALSE;
if (!(AudioPortPtr[i] = (struct MsgPort *) CreateMsgPort()))
{ freefx();
draw(MUSICICON, ICONY, BLACKENED);
mode = FALSE;
say("No port for effects!", RED);
anykey(TRUE);
return FALSE;
} else if (!(AudioRqPtr[i] = (struct IOAudio *) CreateIORequest(AudioPortPtr[i], sizeof(struct IOAudio))))
{ freefx();
draw(MUSICICON, ICONY, BLACKENED);
mode = FALSE;
say("No I/O memory for effects!", RED);
anykey(TRUE);
return FALSE;
} }
AudioRqPtr[0]->ioa_Request.io_Message.mn_ReplyPort = AudioPortPtr[0];
AudioRqPtr[0]->ioa_Request.io_Message.mn_Node.ln_Pri = 127;
AudioRqPtr[0]->ioa_AllocKey = 0;
AudioRqPtr[0]->ioa_Data = chan;
AudioRqPtr[0]->ioa_Length = 1;
if (AudioClosed = OpenDevice(AUDIONAME, 0L, (struct IORequest *) AudioRqPtr[0], 0L))
{ freefx();
draw(MUSICICON, ICONY, BLACKENED);
mode = FALSE;
say("Can't allocate all channels for effects!", RED);
anykey(TRUE);
return FALSE;
} else
{ for (i = 1; i <= 3; i++)
CopyMem(AudioRqPtr[0], AudioRqPtr[i], sizeof(struct IOAudio));
return TRUE;
} }
void resettime(void)
{ GetSysTime(StartValPtr);
srand((UWORD) StartValPtr->tv_micro);
}
void rundown(SBYTE player)
{ TEXT tempstring[6];
SBYTE i, j, x, y;
UWORD counter = 0, code, qual;
ABOOL done = FALSE;
ULONG levelbonus, timebonus, tailbonus, class;
UBYTE multiply = worm[player].multi * players;
struct IntuiMessage* MsgPtr;
clearscreen();
SetAPen(MainWindowPtr->RPort, worm[player].colour);
Image.ImageData = ImageData[TREASURE];
DrawImage(MainWindowPtr->RPort, &Image, 201, 103);
Move(MainWindowPtr->RPort, 218, 108);
Text(MainWindowPtr->RPort, "Level Bonus: ## x ##00 =", 27);
stci_d(tempstring, multiply);
align(tempstring, 2, ' ');
Move(MainWindowPtr->RPort, 218 + (FONTX * 21), 108);
Text(MainWindowPtr->RPort, tempstring, 2);
stci_d(tempstring, level - 1);
align(tempstring, 2, ' ');
Move(MainWindowPtr->RPort, 218 + (FONTX * 16), 108);
Text(MainWindowPtr->RPort, tempstring, 2);
Image.ImageData = ImageData[CLOCK];
DrawImage(MainWindowPtr->RPort, &Image, 201, 111);
Move(MainWindowPtr->RPort, 218, 116);
Text(MainWindowPtr->RPort, " Time Bonus: ##:## x ##0 =", 27);
stci_d(tempstring, multiply);
align(tempstring, 2, ' ');
Move(MainWindowPtr->RPort, 226 + (FONTX * 21), 116);
Text(MainWindowPtr->RPort, tempstring, 2);
stci_d(tempstring, secondsleft / 60);
align(tempstring, 2, ' ');
Move(MainWindowPtr->RPort, 226 + (FONTX * 12), 116);
Text(MainWindowPtr->RPort, tempstring, 2);
stci_d(tempstring, secondsleft % 60);
align(tempstring, 2, '0');
Move(MainWindowPtr->RPort, 226 + (FONTX * 15), 116);
Text(MainWindowPtr->RPort, tempstring, 2);
Image.ImageData = ImageData[FIRSTTAIL + player];
DrawImage(MainWindowPtr->RPort, &Image, 201, 119);
Move(MainWindowPtr->RPort, 218, 124);
Text(MainWindowPtr->RPort, " Tail Bonus: #### x ## =", 27);
stci_d(tempstring, multiply);
align(tempstring, 2, ' ');
Move(MainWindowPtr->RPort, 226 + (FONTX * 22), 124);
Text(MainWindowPtr->RPort, tempstring, 2);
for (x = 0; x <= FIELDX; x++)
for (y = 0; y <= FIELDY; y++)
if (field[x][y] == FIRSTTAIL + player)
counter++;
stci_d(tempstring, counter);
align(tempstring, 4, ' ');
Move(MainWindowPtr->RPort, 226 + (FONTX * 13), 124);
Text(MainWindowPtr->RPort, tempstring, 4);
levelbonus = (level - 1) * 100 * multiply;
timebonus = secondsleft * 10 * multiply;
tailbonus = counter * multiply;
for (i = 0; i <= 3; i++)
if (worm[i].control != NONE)
for (j = 0; j <= LASTOBJECT; j++)
stat(i, j);
while (!done)
{ while (MsgPtr = (struct IntuiMessage *) GetMsg(MainWindowPtr->UserPort))
{ class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
ReplyMsg(MsgPtr);
if (class == IDCMP_RAWKEY && (!(qual & IEQUALIFIER_REPEAT)) && code < KEYUP)
done = TRUE;
}
if (done)
{ wormscore
( player,
(levelbonus / multiply) +
( timebonus / multiply) +
( tailbonus / multiply)
);
levelbonus = timebonus = tailbonus = 0;
}
SetAPen(MainWindowPtr->RPort, worm[player].colour);
stci_d(tempstring, levelbonus);
align(tempstring, 5, ' ');
Move(MainWindowPtr->RPort, 218 + (FONTX * 27), 108);
Text(MainWindowPtr->RPort, tempstring, 5);
stci_d(tempstring, timebonus);
align(tempstring, 5, ' ');
Move(MainWindowPtr->RPort, 226 + (FONTX * 26), 116);
Text(MainWindowPtr->RPort, tempstring, 5);
stci_d(tempstring, tailbonus);
align(tempstring, 5, ' ');
Move(MainWindowPtr->RPort, 226 + (FONTX * 26), 124);
Text(MainWindowPtr->RPort, tempstring, 5);
done = TRUE;
if (levelbonus)
{ levelbonus -= multiply;
wormscore(player, 1);
done = FALSE;
}
if (timebonus)
{ timebonus -= multiply;
wormscore(player, 1);
done = FALSE;
}
if (tailbonus)
{ tailbonus -= multiply;
wormscore(player, 1);
done = FALSE;
}
effect(FXRUNDOWN);
}
clearkybd();
effect(FXENDOFLEVEL);
anykey(FALSE);
}
void say(STRPTR sentence, COLOUR colour)
{ SBYTE length = (SBYTE) strlen(sentence);
/* truncate text */
if (length > SAYLIMIT)
*(sentence + SAYLIMIT - 1) = *(sentence + SAYLIMIT - 2) = *(sentence + SAYLIMIT - 3) = '.';
/* clear areas to left, right and top of text, respectively */
SetAPen(MainWindowPtr->RPort, BLACK);
RectFill
( MainWindowPtr->RPort,
SAYSTARTXPIXEL,
2,
(SCREENXPIXEL / 2) - (length * FONTX / 2),
10
);
RectFill
( MainWindowPtr->RPort,
(SCREENXPIXEL / 2) + (length * FONTX / 2) + 1,
2,
SAYENDXPIXEL,
10
);
Move(MainWindowPtr->RPort, (SCREENXPIXEL / 2) - (length * FONTX / 2), 2);
Draw(MainWindowPtr->RPort, (SCREENXPIXEL / 2) + (length * FONTX / 2), 2);
/* render shadow text */
SetAPen(MainWindowPtr->RPort, MEDIUMGREY);
Move(MainWindowPtr->RPort, (SCREENXPIXEL / 2) - (length * FONTX / 2) + 1, FONTY + 1);
Text(MainWindowPtr->RPort, sentence, length);
/* render actual text */
SetDrMd(MainWindowPtr->RPort, JAM1);
SetAPen(MainWindowPtr->RPort, colour);
Move(MainWindowPtr->RPort, (SCREENXPIXEL / 2) - (length * FONTX / 2), FONTY);
Text(MainWindowPtr->RPort, sentence, length);
SetDrMd(MainWindowPtr->RPort, JAM2);
}
void sendreadrequest(void)
{ JoyRqPtr->io_Command = GPD_READEVENT;
JoyRqPtr->io_Flags = NULL;
JoyRqPtr->io_Length = sizeof(struct InputEvent);
JoyRqPtr->io_Data = (APTR) &GameEvent;
SendIO(JoyRqPtr);
}
MODULE void setpointer(SBYTE pointer) {
switch (pointer) {
case GOLD:
SetRGB4(&ScreenPtr->ViewPort, 17, 10, 8, 3); /* fill */
SetRGB4(&ScreenPtr->ViewPort, 18, 8, 4, 2); /* shadow */
SetRGB4(&ScreenPtr->ViewPort, 19, 12, 12, 2); /* shine */
SetPointer(MainWindowPtr, &CustomPointer, 6, 5, -3, -2);
break;
case SILVER:
SetRGB4(&ScreenPtr->ViewPort, 17, 10, 10, 10); /* fill */
SetRGB4(&ScreenPtr->ViewPort, 18, 6, 6, 6); /* shadow */
SetRGB4(&ScreenPtr->ViewPort, 19, 15, 15, 15); /* shine */
SetPointer(MainWindowPtr, &CustomPointer, 6, 5, -3, -2);
break;
case EMPTY:
SetRGB4(&ScreenPtr->ViewPort, 17, 2, 2, 2); /* fill */
SetRGB4(&ScreenPtr->ViewPort, 18, 0, 0, 0); /* shadow */
SetRGB4(&ScreenPtr->ViewPort, 19, 6, 6, 6); /* shine */
SetPointer(MainWindowPtr, &CustomPointer, 6, 5, -3, -2);
break;
case WOOD:
SetRGB4(&ScreenPtr->ViewPort, 17, 8, 4, 2); /* fill */
SetRGB4(&ScreenPtr->ViewPort, 18, 2, 2, 2); /* shadow */
SetRGB4(&ScreenPtr->ViewPort, 19, 10, 8, 3); /* shine */
SetPointer(MainWindowPtr, &CustomPointer, 6, 5, -3, -2);
break;
case STONE:
SetRGB4(&ScreenPtr->ViewPort, 17, 0, 0, 0); /* fill */
SetRGB4(&ScreenPtr->ViewPort, 18, 2, 2, 2); /* shadow */
SetRGB4(&ScreenPtr->ViewPort, 19, 6, 6, 6); /* shine */
SetPointer(MainWindowPtr, &CustomPointer, 6, 5, -3, -2);
break;
case METAL:
SetRGB4(&ScreenPtr->ViewPort, 17, 6, 6, 15); /* fill */
SetRGB4(&ScreenPtr->ViewPort, 18, 3, 3, 15); /* shadow */
SetRGB4(&ScreenPtr->ViewPort, 19, 10, 10, 10); /* shine */
SetPointer(MainWindowPtr, &CustomPointer, 6, 5, -3, -2);
break;
default:
SetRGB4(&ScreenPtr->ViewPort, 17, 14, 4, 4); /* fill */
SetRGB4(&ScreenPtr->ViewPort, 18, 3, 3, 3); /* shadow */
SetRGB4(&ScreenPtr->ViewPort, 19, 12, 12, 12); /* shine */
ClearPointer(MainWindowPtr);
break; }
}
void stat(SBYTE player, SBYTE line)
{ ABOOL print = TRUE;
SBYTE i, len, theline;
TEXT output[9];
strcpy(output, " "); /* 8 spaces */
switch (line)
{
case BONUS:
do
{ worm[player].oldscore += (LIFEMODULO - (worm[player].oldscore % LIFEMODULO));
if (worm[player].score >= worm[player].oldscore)
{ worm[player].lives++;
stat(player, LIFE);
}
} while (worm[player].score > worm[player].oldscore);
worm[player].oldscore = worm[player].score;
if (worm[player].multi > 1)
SetAPen(MainWindowPtr->RPort, WHITE);
else
SetAPen(MainWindowPtr->RPort, worm[player].colour);
stcl_d(output, worm[player].score);
for (i = 0; i <= 8; i++)
if (!output[i])
output[i] = ' ';
theline = 0;
if (worm[player].score <= 999999L)
len = 6;
else
{ /* assert(worm[player].score <= 99999999L); */
len = 8;
}
break;
case LIFE:
if (worm[player].lives > STARTLIVES)
{ SetAPen(MainWindowPtr->RPort, WHITE);
if (worm[player].lives > LIVESLIMIT)
worm[player].lives = LIVESLIMIT;
} else SetAPen(MainWindowPtr->RPort, worm[player].colour);
stci_d(output, worm[player].lives);
for (i = 0; i <= 2; i++)
if (!output[i])
{ output[i] = ' ';
break;
}
theline = 1;
len = 3;
break;
case BIAS:
if (worm[player].bias > 0)
{ if (worm[player].bias > BIASLIMIT)
worm[player].bias = BIASLIMIT;
SetAPen(MainWindowPtr->RPort, WHITE);
} else
SetAPen(MainWindowPtr->RPort, worm[player].colour);
stci_d(output, worm[player].bias);
for (i = 0; i <= 2; i++)
if (!output[i])
{ output[i] = ' ';
break;
}
theline = 2;
len = 3;
break;
case NITRO:
SetAPen(MainWindowPtr->RPort, worm[player].colour);
if (worm[player].speed == FAST)
strcpy(output, STATFAST);
else if (worm[player].speed == NORMAL)
strcpy(output, STATNORMAL);
else /* assumes worm[player].speed == SLOW */
strcpy(output, STATSLOW);
theline = 3;
len = 6;
break;
case AMMO:
if (worm[player].ammo)
{ if (worm[player].ammo > AMMOLIMIT)
worm[player].ammo = AMMOLIMIT;
SetAPen(MainWindowPtr->RPort, WHITE);
} else
SetAPen(MainWindowPtr->RPort, worm[player].colour);
stci_d(output, worm[player].ammo);
for (i = 0; i <= 2; i++)
if (!output[i])
{ output[i] = ' ';
break;
}
if (iso)
theline = 4;
else theline = 5;
len = 3;
break;
case POWER:
switch(worm[player].power)
{ case 0:
SetAPen(MainWindowPtr->RPort, worm[player].colour);
strcpy(output, STATSINGLE);
break;
case 2:
SetAPen(MainWindowPtr->RPort, WHITE);
strcpy(output, STATTRIPLE);
break;
case 4:
SetAPen(MainWindowPtr->RPort, WHITE);
strcpy(output, STATQUINTUPLE);
break;
case 6:
SetAPen(MainWindowPtr->RPort, WHITE);
strcpy(output, STATSEPTUPLE);
break;
default:
break;
}
if (iso)
theline = 5;
else theline = 6;
len = 6;
break;
case ARMOUR:
if (worm[player].armour > MODELIMIT)
worm[player].armour = MODELIMIT;
if (worm[player].mode == ARMOUR)
SetAPen(MainWindowPtr->RPort, WHITE);
else
SetAPen(MainWindowPtr->RPort, worm[player].colour);
stci_d(output, worm[player].armour);
for (i = 0; i <= 2; i++)
if (!output[i])
{ output[i] = ' ';
break;
}
if (iso)
theline = 6;
else theline = 8;
len = 3;
break;
case TONGUE:
if (worm[player].tongue > MODELIMIT)
worm[player].tongue = MODELIMIT;
if (worm[player].mode == TONGUE)
SetAPen(MainWindowPtr->RPort, WHITE);
else
SetAPen(MainWindowPtr->RPort, worm[player].colour);
stci_d(output, worm[player].tongue);
for (i = 0; i <= 2; i++)
if (!output[i])
{ output[i] = ' ';
break;
}
if (iso)
theline = 7;
else theline = 9;
len = 3;
break;
default:
print = FALSE;
break;
}
if (print)
{ if (iso)
switch(player)
{
case 0:
Move(MainWindowPtr->RPort, 0 , 8 + (theline * FONTY));
break;
case 1:
Move(MainWindowPtr->RPort, 528, 189 + (theline * FONTY));
break;
case 2:
Move(MainWindowPtr->RPort, 66 , 8 + (theline * FONTY));
break;
case 3:
Move(MainWindowPtr->RPort, 592, 189 + (theline * FONTY));
break;
default:
/* assert(0); */
break;
}
else
{ Move
( MainWindowPtr->RPort,
(FONTX * 3) + (worm[player].statx * ENDXPIXEL),
STARTYPIXEL + 6 + (theline * FONTY) + (worm[player].staty * (ENDYPIXEL - 1 - (11 * FONTY)))
);
}
Text(MainWindowPtr->RPort, output, len);
} }
void stopfx(void)
{ SBYTE i;
if (mode == FX)
for (i = 0; i <= 3; i++)
if (eversent[i] && (!(CheckIO(AudioRqPtr[i]))))
{ AbortIO(AudioRqPtr[i]);
WaitIO(AudioRqPtr[i]);
} }
void titlescreen(void)
{ SBYTE lisa = 0, object = LASTOBJECT, player;
SWORD descx = FIRSTDESCX;
ULONG class;
UWORD code, qual;
struct IntuiMessage* MsgPtr;
struct Gadget* WhichGadgetPtr;
struct MenuItem* ItemPtr;
effect(FXTITLESCREEN);
Forbid();
MainWindowPtr->Flags &= ~WFLG_RMBTRAP;
Permit();
clearscreen();
SetMenuStrip(MainWindowPtr, MenuPtr);
for (player = 0; player <= 3; player++)
GT_SetGadgetAttrs(CycleGadgetPtr[player], MainWindowPtr, NULL, GA_Disabled, FALSE, TAG_DONE);
GT_SetGadgetAttrs(CheckboxGadgetPtr, MainWindowPtr, NULL, GA_Disabled, FALSE, TAG_DONE);
clearkybd();
clearjoystick();
hiscores();
hiscorenames();
SetDrMd(MainWindowPtr->RPort, JAM1);
SetAPen(MainWindowPtr->RPort, BLACK);
Move(MainWindowPtr->RPort, STARTXPIXEL + 9, 193);
Text(MainWindowPtr->RPort, "Spacebar: Field Editor ", 23);
Move(MainWindowPtr->RPort, STARTXPIXEL + 9, 213);
Text(MainWindowPtr->RPort, " F: Sound Effects", 23);
Move(MainWindowPtr->RPort, STARTXPIXEL + 9, 223);
Text(MainWindowPtr->RPort, " M: Music ", 23);
SetAPen(MainWindowPtr->RPort, WHITE);
Move(MainWindowPtr->RPort, STARTXPIXEL + 8, 192);
Text(MainWindowPtr->RPort, "Spacebar: Field Editor ", 23);
Move(MainWindowPtr->RPort, STARTXPIXEL + 8, 212);
Text(MainWindowPtr->RPort, " F: Sound Effects", 23);
Move(MainWindowPtr->RPort, STARTXPIXEL + 8, 222);
Text(MainWindowPtr->RPort, " M: Music ", 23);
SetDrMd(MainWindowPtr->RPort, JAM2);
effect(FXSTAMPED);
DrawImage(MainWindowPtr->RPort, &Logo, 203, 22);
do
{ TimerRqPtr->tr_node.io_Command = TR_ADDREQUEST;
TimerRqPtr->tr_time.tv_secs = 0;
TimerRqPtr->tr_time.tv_micro = ANIMDELAY;
SendIO(TimerRqPtr);
if (descx == FIRSTDESCX)
{ if (++object > LASTOBJECT)
object = 0;
say(objectdesc[object], WHITE);
Image.ImageData = ImageData[object];
DrawImage(MainWindowPtr->RPort, &Image, SECONDDESCX, DESCY);
}
SetAPen(MainWindowPtr->RPort, BLACK);
Move(MainWindowPtr->RPort, descx - 1, DESCY - 1);
Draw(MainWindowPtr->RPort, descx - 1, DESCY + 1 + SQUAREY);
Move(MainWindowPtr->RPort, descx + 1 + SQUAREX, DESCY - 1);
Draw(MainWindowPtr->RPort, descx + 1 + SQUAREX, DESCY + 1 + SQUAREY);
Image.ImageData = ImageData[object];
DrawImage(MainWindowPtr->RPort, &Image, descx, DESCY);
if (++descx > SECONDDESCX)
descx = FIRSTDESCX;
while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
{ WhichGadgetPtr = (struct Gadget *) MsgPtr->IAddress;
class = MsgPtr->Class;
code = MsgPtr->Code;
qual = MsgPtr->Qualifier;
GT_ReplyIMsg(MsgPtr);
switch (class) {
case IDCMP_RAWKEY:
if (!(qual & IEQUALIFIER_REPEAT))
switch (code) {
case F:
toggle(F);
break;
case M:
toggle(M);
break;
case SPACEBAR:
effect(FXCLICK);
a = FIELDEDIT;
break;
case F1:
case ALPHAONE:
case NUMERICONE:
effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (--worm[0].control < 0)
worm[0].control = 2;
} else
{ if (++worm[0].control > 2)
worm[0].control = 0;
}
GT_SetGadgetAttrs(CycleGadgetPtr[0], MainWindowPtr, NULL, GTCY_Active, worm[0].control, TAG_DONE);
break;
case F2:
case ALPHATWO:
case NUMERICTWO:
effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (--worm[1].control < 0)
worm[1].control = 2;
} else
{ if (++worm[1].control > 2)
worm[1].control = 0;
}
GT_SetGadgetAttrs(CycleGadgetPtr[1], MainWindowPtr, NULL, GTCY_Active, worm[1].control, TAG_DONE);
break;
case F3:
case ALPHATHREE:
case NUMERICTHREE:
effect(FXCLICK);
if (joy)
{ if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (--worm[2].control < 0)
worm[2].control = 2;
} else
{ if (++worm[2].control > 2)
worm[2].control = 0;
} }
else if (worm[2].control == NONE)
worm[2].control = AMIGA;
else
worm[2].control = NONE;
GT_SetGadgetAttrs(CycleGadgetPtr[2], MainWindowPtr, NULL, GTCY_Active, worm[2].control, TAG_DONE);
break;
case F4:
case ALPHAFOUR:
case NUMERICFOUR:
effect(FXCLICK);
if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ if (--worm[3].control < 0)
worm[3].control = 2;
} else
{ if (++worm[3].control > 2)
worm[3].control = 0;
}
GT_SetGadgetAttrs(CycleGadgetPtr[3], MainWindowPtr, NULL, GTCY_Active, worm[3].control, TAG_DONE);
break;
case RETURN:
case ENTER:
a = PLAYGAME;
break;
case I:
effect(FXCLICK);
iso = !iso;
GT_SetGadgetAttrs(CheckboxGadgetPtr, MainWindowPtr, NULL, GTCB_Checked, iso, TAG_DONE);
break;
case ESCAPE:
if (verify())
cleanexit(EXIT_SUCCESS);
break;
case HELP:
helpabout();
break;
case INTERNATIONALONE:
if (lisa == 2)
{ say(FIRSTLISA, RED);
anykey(FALSE);
lisa = 0;
} else
lisa = 1;
break;
case INTERNATIONALTWO:
if (lisa == 1)
{ say(SECONDLISA, BLUE);
anykey(FALSE);
lisa = 0;
} else
lisa = 2;
break;
default:
break;
}
break;
case IDCMP_MENUPICK:
while (code != MENUNULL)
{ ItemPtr = ItemAddress(MenuPtr, code);
switch (MENUNUM(code))
{
case MN_PROJECT:
switch (ITEMNUM(code))
{
case IN_NEW:
effect(FXFILENEW);
newfields();
say("New done.", WHITE);
anykey(TRUE);
say(objectdesc[object], WHITE);
break;
case IN_OPEN:
effect(FXFILEOPEN);
fileopen(FALSE);
say(objectdesc[object], WHITE);
break;
case IN_REVERT:
fileopen(TRUE);
say(objectdesc[object], WHITE);
break;
case IN_SAVE:
effect(FXFILESAVE);
filesaveas(FALSE);
say(objectdesc[object], WHITE);
break;
case IN_SAVEAS:
effect(FXFILESAVEAS);
filesaveas(TRUE);
say(objectdesc[object], WHITE);
break;
case IN_QUIT:
if (verify())
cleanexit(EXIT_SUCCESS);
break;
default:
break;
}
break;
case MN_SETTINGS:
switch(ITEMNUM(code))
{
case IN_CREATEICONS:
if (ItemPtr->Flags & CHECKED)
icons = TRUE;
else icons = FALSE;
break;
default:
break;
}
break;
case MN_HELP:
switch(ITEMNUM(code))
{
case IN_MANUAL:
helpmanual();
break;
case IN_ABOUT:
helpabout();
break;
case IN_CREATURES:
help(ORB);
break;
case IN_OBJECTS:
help(AFFIXER);
break;
}
break;
default:
break;
}
code = ItemPtr->NextSelect;
}
break;
case IDCMP_MOUSEBUTTONS:
if (code == SELECTDOWN)
if (ignore)
ignore = FALSE;
else a = PLAYGAME;
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(MainWindowPtr);
GT_EndRefresh(MainWindowPtr, TRUE);
break;
case IDCMP_GADGETUP:
if (WhichGadgetPtr == CheckboxGadgetPtr)
iso = !iso;
else
{ for (player = 0; player <= 3; player++)
if (WhichGadgetPtr == CycleGadgetPtr[player])
{ if (code == HUMAN && player == 2 && (!joy))
{ if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
worm[2].control = NONE;
else
worm[2].control = AMIGA;
GT_SetGadgetAttrs(CycleGadgetPtr[2], MainWindowPtr, NULL, GTCY_Active, worm[2].control, TAG_DONE);
} else
worm[player].control = code;
break;
}
}
break;
case IDCMP_ACTIVEWINDOW:
ignore = TRUE;
break;
case IDCMP_CLOSEWINDOW:
cleanexit(EXIT_SUCCESS);
break;
default:
/* IDCMP_MENUVERIFY, IDCMP_INTUITICKS */
break;
} }
if (joy && GetMsg(JoyPortPtr))
{ if (GameEvent.ie_Code == IECODE_LBUTTON)
a = PLAYGAME;
sendreadrequest();
}
if (a == PLAYGAME)
{ if (worm[0].control == NONE && worm[1].control == NONE && worm[2].control == NONE && worm[3].control == NONE)
{ say("No worms active!", WHITE);
anykey(TRUE);
a = GAMEOVER;
} }
if (CheckIO(TimerRqPtr))
draw(CLOCKICON, ICONY, CLOCK);
else draw(CLOCKICON, ICONY, BLACKENED);
WaitIO(TimerRqPtr);
} while (a == GAMEOVER);
for (player = 0; player <= 3; player++)
GT_SetGadgetAttrs(CycleGadgetPtr[player], MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
GT_SetGadgetAttrs(CheckboxGadgetPtr, MainWindowPtr, NULL, GA_Disabled, TRUE, TAG_DONE);
Image.ImageData = ImageData[BLACKENED];
DrawImage(MainWindowPtr->RPort, &Image, FIRSTDESCX, DESCY);
DrawImage(MainWindowPtr->RPort, &Image, SECONDDESCX, DESCY);
if (a == FIELDEDIT)
fieldedit();
else
{ newgame();
clearkybd();
Forbid();
MainWindowPtr->Flags |= WFLG_RMBTRAP;
Permit();
} }
MODULE void toggle(SBYTE key)
{ PERSIST ABOOL songstarted = FALSE;
switch(key)
{
case F:
if (mode == FX) /* F in FX mode: no sound */
{ freefx();
mode = FALSE;
draw(MUSICICON, ICONY, BLACKENED);
} else if (fxable > 0) /* F otherwise: change to FX mode */
{ if (mode == MUSIC) /* stop any music that is playing */
{ StopPlayer();
FreePlayer();
}
if (fxable == 3) /* load samples if needed */
loadthefx();
if (fxable == 1) /* if we have samples in memory */
{ if (beginfx())
{ mode = FX;
effect(FXFX);
draw(MUSICICON, ICONY, FX);
} } }
break;
case M:
if (mode == MUSIC) /* M in MUSIC mode: no sound */
{ StopPlayer();
FreePlayer();
mode = FALSE;
draw(MUSICICON, ICONY, BLACKENED);
} else if (musicable > 0) /* M otherwise: change to music mode */
{ if (mode == FX) /* stop any samples that are playing */
freefx();
/* Of course, these statements are ordered in this
way for a reason, so don't change it. */
if (musicable == 3)
loadthemusic();
if (musicable == 1)
{ if (GetPlayer(0))
{ say("No channels for music!", RED);
anykey(TRUE);
mode = FALSE;
draw(MUSICICON, ICONY, BLACKENED);
} else
{ if (songstarted)
ContModule(SongPtr);
else
{ PlayModule(SongPtr);
songstarted = TRUE;
}
mode = MUSIC;
draw(MUSICICON, ICONY, MUSIC);
} } }
break;
default:
break;
} }
MODULE void underline(SBYTE square)
{ /* Removes old underline, draws new underline.
square: which square-type to underline, or -1 for clear only.
Squares which do not correspond to any pseudo-gadgets
(eg. objects) are converted to -1s. */
PERSIST SWORD oldy = -1;
SWORD y;
switch(square)
{
case GOLD:
y = UNDERLINEOFFSET;
break;
case SILVER:
y = UNDERLINEOFFSET + (SQUAREY * 3);
break;
case EMPTY:
y = UNDERLINEOFFSET + (SQUAREY * 6);
break;
case WOOD:
y = UNDERLINEOFFSET + (SQUAREY * 9);
break;
case STONE:
y = UNDERLINEOFFSET + (SQUAREY * 12);
break;
case METAL:
y = UNDERLINEOFFSET + (SQUAREY * 15);
break;
case ONE:
y = UNDERLINEOFFSET + (SQUAREY * 18);
break;
case TWO:
y = UNDERLINEOFFSET + (SQUAREY * 21);
break;
case START:
y = UNDERLINEOFFSET + (SQUAREY * 24);
break;
default:
square = -1;
break;
}
if (oldy != -1)
{ SetAPen(MainWindowPtr->RPort, BLACK);
Move(MainWindowPtr->RPort, STARTXPIXEL - SQUAREX + 1, oldy);
Draw(MainWindowPtr->RPort, STARTXPIXEL - SQUAREX + 1, oldy + SQUAREY + 3);
}
if (square != -1)
{ SetAPen(MainWindowPtr->RPort, WHITE);
Move(MainWindowPtr->RPort, STARTXPIXEL - SQUAREX + 1, y);
Draw(MainWindowPtr->RPort, STARTXPIXEL - SQUAREX + 1, y + SQUAREY + 3);
oldy = y;
} }
ABOOL verify(void)
{ pausetimer();
if (modified && (EasyRequest(MainWindowPtr, &EasyStruct, NULL) == 0))
return FALSE;
else return TRUE;
unpausetimer();
}
void waitasec(void)
{ Delay(50);
}
void systemsetup(void)
{ worm[0].control = NONE;
worm[1].control = HUMAN;
worm[2].control = NONE;
worm[3].control = AMIGA;
}
ABOOL ZOpen(STRPTR fieldname, ABOOL write)
{ if (!write)
if (FilePtr = Open(fieldname, MODE_OLDFILE))
return TRUE;
else return FALSE;
else
if (FilePtr = Open(fieldname, MODE_NEWFILE))
return TRUE;
else return FALSE;
}
ABOOL ZRead(STRPTR IOBuffer, ULONG length)
{ if (Read(FilePtr, IOBuffer, length) == length)
return TRUE;
else return FALSE;
}
ABOOL ZWrite(STRPTR IOBuffer, ULONG length)
{ if (Write(FilePtr, IOBuffer, length) == length)
return TRUE;
else return FALSE;
}
ABOOL ZClose(void)
{ if (Close(FilePtr))
{ FilePtr = NULL;
return TRUE;
} else
{ /* "If Close() returns DOSFALSE, the user has already cancelled an
error requester and the function has already freed the FileHandle
(and even marked it so any attempt to close it again will bring up
the "Software Failure" requester). Therefore FilePtr should be set
to zero in any case." - Jilles Tjoelker. */
FilePtr = NULL;
return FALSE;
} }
void timing(void)
{ ;
}
MODULE void loadthefx(void)
{ UBYTE* p8data;
TEXT saystring[SAYLIMIT + 1];
SBYTE code = 0, i;
SBYTE iobuffer[8]; /* buffer for 8SVX.VHDR */
SBYTE* psample[2]; /* sample pointers */
struct Chunk* p8Chunk; /* pointers for 8SVX parsing */
Voice8Header* pVoice8Header;
ULONG rd8count;
say("Loading sound effects...", WHITE);
fxable = 1;
for (i = 0; i <= SAMPLES; i++)
samp[i].base = NULL;
for (i = 0; i <= SAMPLES; i++)
{ if (!(FilePtr = Open(samp[i].filename, MODE_OLDFILE)))
code = 1; /* can't open file */
else
{ rd8count = Read(FilePtr, iobuffer, 8L);
if (rd8count == -1)
code = 2; /* can't read file */
else if (rd8count < 8)
code = 3; /* not an IFF 8SVX; too short */
else
{ p8Chunk = (struct Chunk *) iobuffer;
if (p8Chunk->ckID != ID_FORM)
code = 4; /* not an IFF FORM */
else if (!(fbase = (UBYTE *) AllocMem(fsize = p8Chunk->ckSize, MEMF_PUBLIC | MEMF_CLEAR)))
code = 5; /* no memory for read */
else
{ p8data = fbase;
rd8count = Read(FilePtr, p8data, p8Chunk->ckSize);
if (rd8count == -1)
code = 6; /* read error */
else if (rd8count < p8Chunk->ckSize)
code = 7; /* malformed IFF; too short */
else if (MAKE_ID(*p8data, *(p8data + 1), *(p8data + 2), *(p8data + 3)) != ID_8SVX)
code = 8; /* not an IFF 8SVX */
else
{ p8data = p8data + 4;
while (p8data < fbase + fsize)
{ p8Chunk = (struct Chunk *) p8data;
switch(p8Chunk->ckID) {
case ID_VHDR:
pVoice8Header = (Voice8Header *) (p8data + 8L);
break;
case ID_BODY:
psample[0] = (SBYTE *) (p8data + 8L);
psample[1] = psample[0] + pVoice8Header->oneShotHiSamples;
samp[i].length[0] = (ULONG) pVoice8Header->oneShotHiSamples;
samp[i].length[1] = (ULONG) pVoice8Header->repeatHiSamples;
/* To grab the volume level from the IFF
8SVX file itself, add this here:
samp[i].volume = (SBYTE) (pVoice8Header->volume / 156); */
break;
default:
break;
}
p8data += 8L + p8Chunk->ckSize;
if (p8Chunk->ckSize & 1L == 1)
p8data++;
}
if (samp[i].length[0] == 0)
samp[i].bank = 1;
else samp[i].bank = 0;
if (samp[i].length[samp[i].bank] <= 102400)
samp[i].size = samp[i].length[samp[i].bank];
else samp[i].size = 102400;
samp[i].base = (UBYTE *) AllocMem(samp[i].size, MEMF_CHIP | MEMF_CLEAR);
if (!samp[i].base)
code = 9; /* no chip memory */
else
{ CopyMem(psample[samp[i].bank], samp[i].base, samp[i].size);
psample[samp[i].bank] += samp[i].size;
samp[i].speed = PALCLOCK / pVoice8Header->samplesPerSec;
/* perhaps we should have a different value for
DBLPAL screens? */
if (fbase)
{ FreeMem(fbase, fsize);
fbase = NULL;
}
if (FilePtr)
{ Close(FilePtr);
FilePtr = NULL;
} } } } } }
if (code)
{ freefx();
fxable = 0;
strcpy(saystring, samp[i].filename);
strcat(saystring, ": ");
strcat(saystring, sfxerror[code]);
say(saystring, RED);
anykey(TRUE);
break;
} } }
MODULE void loadthemusic(void)
{ if (!(MEDPlayerBase = (struct MEDPlayerBase *) OpenLibrary("medplayer.library", 0L)))
{ say("Can't open MEDPlayer.library!", RED);
anykey(TRUE);
} else
{ say("Loading music...", WHITE);
if (SongPtr = (struct MMD0 *) LoadModule("PROGDIR:WormWars.MED"))
musicable = TRUE;
else
{ say("Can't load music!", RED);
anykey(TRUE);
} } }
MODULE void dot(SBYTE x, SBYTE y)
{ SWORD xx, yy;
/* Squares are dotted as follows:
012345678
0.........
1.........
2...WWW...
3...WWWB..
4....BBB..
5......... */
xx = (x * SQUAREX) + STARTXPIXEL;
yy = (y * SQUAREY) + STARTYPIXEL;
if (sticky)
SetAPen(MainWindowPtr->RPort, RED);
else SetAPen(MainWindowPtr->RPort, WHITE);
WritePixel(MainWindowPtr->RPort, xx + 3, yy + 2);
WritePixel(MainWindowPtr->RPort, xx + 4, yy + 2);
WritePixel(MainWindowPtr->RPort, xx + 5, yy + 2);
WritePixel(MainWindowPtr->RPort, xx + 3, yy + 3);
WritePixel(MainWindowPtr->RPort, xx + 4, yy + 3);
WritePixel(MainWindowPtr->RPort, xx + 5, yy + 3);
SetAPen(MainWindowPtr->RPort, BLACK);
WritePixel(MainWindowPtr->RPort, xx + 6, yy + 3);
WritePixel(MainWindowPtr->RPort, xx + 4, yy + 4);
WritePixel(MainWindowPtr->RPort, xx + 5, yy + 4);
WritePixel(MainWindowPtr->RPort, xx + 6, yy + 4);
}
void clearscreen(void)
{ SBYTE player;
DrawImage
( MainWindowPtr->RPort,
&Background,
0,
0
);
if (mode == MUSIC)
draw(MUSICICON, ICONY, MUSIC);
else if (mode == FX)
draw(MUSICICON, ICONY, FX);
else draw(MUSICICON, ICONY, BLACKENED);
draw(CLOCKICON, ICONY, CLOCK);
if (a != FIELDEDIT)
if (!iso)
{ for (player = 0; player <= 3; player++)
{ if (worm[player].control != NONE)
{ Image.ImageData = ImageData[BONUS];
DrawImage
( MainWindowPtr->RPort,
&Image,
(worm[player].statx * ENDXPIXEL) + FONTX,
STARTYPIXEL + 1 + (worm[player].staty * (ENDYPIXEL - 1 - (11 * FONTY)))
);
Image.ImageData = ImageData[LIFE];
DrawImage
( MainWindowPtr->RPort,
&Image,
(worm[player].statx * ENDXPIXEL) + FONTX,
STARTYPIXEL + 1 + (1 * FONTY) + (worm[player].staty * (ENDYPIXEL - 1 - (11 * FONTY)))
);
Image.ImageData = ImageData[BIAS];
DrawImage
( MainWindowPtr->RPort,
&Image,
(worm[player].statx * ENDXPIXEL) + FONTX,
STARTYPIXEL + 1 + (2 * FONTY) + (worm[player].staty * (ENDYPIXEL - 1 - (11 * FONTY)))
);
Image.ImageData = ImageData[NITRO];
DrawImage
( MainWindowPtr->RPort,
&Image,
(worm[player].statx * ENDXPIXEL) + FONTX,
STARTYPIXEL + 1 + (3 * FONTY) + (worm[player].staty * (ENDYPIXEL - 1 - (11 * FONTY)))
);
Image.ImageData = ImageData[AMMO];
DrawImage
( MainWindowPtr->RPort,
&Image,
(worm[player].statx * ENDXPIXEL) + FONTX,
STARTYPIXEL + 1 + (5 * FONTY) + (worm[player].staty * (ENDYPIXEL - 1 - (11 * FONTY)))
);
Image.ImageData = ImageData[POWER];
DrawImage
( MainWindowPtr->RPort,
&Image,
(worm[player].statx * ENDXPIXEL) + FONTX,
STARTYPIXEL + 1 + (6 * FONTY) + (worm[player].staty * (ENDYPIXEL - 1 - (11 * FONTY)))
);
Image.ImageData = ImageData[ARMOUR];
DrawImage
( MainWindowPtr->RPort,
&Image,
(worm[player].statx * ENDXPIXEL) + FONTX,
STARTYPIXEL + 1 + (8 * FONTY) + (worm[player].staty * (ENDYPIXEL - 1 - (11 * FONTY)))
);
Image.ImageData = ImageData[TONGUE];
DrawImage
( MainWindowPtr->RPort,
&Image,
(worm[player].statx * ENDXPIXEL) + FONTX,
STARTYPIXEL + 1 + (9 * FONTY) + (worm[player].staty * (ENDYPIXEL - 1 - (11 * FONTY)))
);
} } }
else /* assert (iso); */
{ if (worm[0].control != NONE || worm[2].control != NONE)
{ Image.ImageData = ImageData[BONUS];
DrawImage(MainWindowPtr->RPort, &Image, 54, 4);
Image.ImageData = ImageData[LIFE];
DrawImage(MainWindowPtr->RPort, &Image, 54, 12);
Image.ImageData = ImageData[BIAS];
DrawImage(MainWindowPtr->RPort, &Image, 54, 20);
Image.ImageData = ImageData[NITRO];
DrawImage(MainWindowPtr->RPort, &Image, 54, 28);
Image.ImageData = ImageData[AMMO];
DrawImage(MainWindowPtr->RPort, &Image, 54, 36);
Image.ImageData = ImageData[POWER];
DrawImage(MainWindowPtr->RPort, &Image, 54, 44);
Image.ImageData = ImageData[ARMOUR];
DrawImage(MainWindowPtr->RPort, &Image, 54, 52);
Image.ImageData = ImageData[TONGUE];
DrawImage(MainWindowPtr->RPort, &Image, 54, 60);
}
if (worm[1].control != NONE || worm[3].control != NONE)
{ Image.ImageData = ImageData[BONUS];
DrawImage(MainWindowPtr->RPort, &Image, 579, 183);
Image.ImageData = ImageData[LIFE];
DrawImage(MainWindowPtr->RPort, &Image, 579, 191);
Image.ImageData = ImageData[BIAS];
DrawImage(MainWindowPtr->RPort, &Image, 579, 199);
Image.ImageData = ImageData[NITRO];
DrawImage(MainWindowPtr->RPort, &Image, 579, 207);
Image.ImageData = ImageData[AMMO];
DrawImage(MainWindowPtr->RPort, &Image, 579, 215);
Image.ImageData = ImageData[POWER];
DrawImage(MainWindowPtr->RPort, &Image, 579, 223);
Image.ImageData = ImageData[ARMOUR];
DrawImage(MainWindowPtr->RPort, &Image, 579, 231);
Image.ImageData = ImageData[TONGUE];
DrawImage(MainWindowPtr->RPort, &Image, 579, 239);
} } }
void datestamp(void)
{ ULONG seconds, micros;
struct ClockData Date;
TEXT temp[5];
CurrentTime(&seconds, µs);
Amiga2Date(seconds, &Date);
stci_d(times, Date.hour); /* hh */
align(times, 2, ' ');
times[2] = ':'; /* hh: */
times[3] = 0;
stci_d(temp, Date.min);
align(temp, 2, '0');
temp[2] = 0;
strcat(times, temp); /* hh:mm */
stci_d(date, Date.mday); /* dd */
align(date, 2, ' ');
date[2] = '/';
date[3] = 0; /* dd/ */
stci_d(temp, Date.month);
align(temp, 2, ' ');
temp[2] = 0;
strcat(date, temp); /* dd/mm */
strcat(date, "/"); /* dd/mm/ */
stci_d(temp, Date.year);
temp[0] = temp[2];
temp[1] = temp[3];
temp[2] = 0;
strcat(date, temp); /* dd/mm/yy */
}
void turborender(void)
{ SBYTE x, y;
for (x = 0; x <= (FIELDX / 2) + 1; x++)
for (y = 0; y <= FIELDY / 2; y++)
{ draw(x, y, board[level][x][y]);
draw(FIELDX - x, y, board[level][FIELDX - x][y]);
draw(x, FIELDY - y, board[level][x][FIELDY - y]);
draw(FIELDX - x, FIELDY - y, board[level][FIELDX - x][FIELDY - y]);
}
if (a == FIELDEDIT)
{ draw(startx[level], starty[level], START);
if (teleport[level][0].alive)
{ draw(teleport[level][0].x, teleport[level][0].y, ONE);
draw(teleport[level][1].x, teleport[level][1].y, TWO);
} } }
MODULE SWORD xpixeltosquare(SWORD x)
{ x = (x - STARTXPIXEL) / SQUAREX;
if (x < 0)
x--;
return (x);
}
MODULE SWORD ypixeltosquare(SWORD y)
{ y = (y - STARTYPIXEL) / SQUAREY;
if (y < 0)
y--;
return (y);
}
MODULE void parsewb(void)
{ struct DiskObject* DiskObject;
char** ToolArray;
char* s;
if ((*WBArg->wa_Name) && (DiskObject = GetDiskObject(WBArg->wa_Name)))
{ ToolArray = (char **) DiskObject->do_ToolTypes;
if (s = (char *) FindToolType(ToolArray, "NOFX"))
fxable = 3;
if (s = (char *) FindToolType(ToolArray, "NOMUSIC"))
musicable = 3;
if (s = (char *) FindToolType(ToolArray, "NOICONS"))
icons = FALSE;
if (s = (char *) FindToolType(ToolArray, "OVERHEAD"))
iso = FALSE;
if (s = (char *) FindToolType(ToolArray, "FILE"))
strcpy(pathname, WBArg->wa_Name);
if (s = (char *) FindToolType(ToolArray, "GREEN"))
{ if (MatchToolValue(s, "HUMAN"))
worm[0].control = HUMAN;
elif (MatchToolValue(s, "AMIGA"))
worm[0].control = AMIGA;
elif (MatchToolValue(s, "NONE"))
worm[0].control = NONE;
}
if (s = (char *) FindToolType(ToolArray, "RED"))
{ if (MatchToolValue(s, "HUMAN"))
worm[1].control = HUMAN;
elif (MatchToolValue(s, "AMIGA"))
worm[1].control = AMIGA;
elif (MatchToolValue(s, "NONE"))
worm[1].control = NONE;
}
if (s = (char *) FindToolType(ToolArray, "BLUE"))
{ if (MatchToolValue(s, "HUMAN"))
worm[2].control = HUMAN;
elif (MatchToolValue(s, "AMIGA"))
worm[2].control = AMIGA;
elif (MatchToolValue(s, "NONE"))
worm[2].control = NONE;
}
if (s = (char *) FindToolType(ToolArray, "YELLOW"))
{ if (MatchToolValue(s, "HUMAN"))
worm[2].control = HUMAN;
elif (MatchToolValue(s, "AMIGA"))
worm[3].control = AMIGA;
elif (MatchToolValue(s, "NONE"))
worm[3].control = NONE;
}
FreeDiskObject(DiskObject);
} }
MODULE void pausetimer(void)
{ GetSysTime(CurrentValPtr);
}
MODULE void unpausetimer(void)
{ GetSysTime(PausedValPtr);
SubTime(PausedValPtr, CurrentValPtr);
AddTime(StartValPtr, PausedValPtr);
}
MODULE UBYTE ReadJoystick(UWORD joynum)
{ extern struct Custom far custom;
UBYTE ret = 0;
UWORD joy;
if (joynum == 0)
joy = custom.joy0dat;
else joy = custom.joy1dat;
ret += (joy >> 1 ^ joy) & 0x0100 ? JOYUP : 0;
ret += (joy >> 1 ^ joy) & 0x0001 ? JOYDOWN : 0;
ret += joy & 0x0200 ? JOYLEFT : 0;
ret += joy & 0x0002 ? JOYRIGHT : 0;
if (joynum == 0)
{ ret += !(CIAPtr->ciapra & 0x0040) ? JOYFIRE1 : 0; /* Read FireButtons */
ret += !(POTGOR & 0x0400) ? JOYFIRE2 : 0; /* on joyport 0 */
} else
{ ret += !(CIAPtr->ciapra & 0x0080) ? JOYFIRE1 : 0; /* Read FireButtons */
ret += !(POTGOR & 0x4000) ? JOYFIRE2 : 0; /* on joyport 1 */
}
return(ret);
}
void joy0(void)
{ UBYTE joyval;
ABOOL fire = FALSE;
SBYTE xx = 0, yy = 0;
if (worm[3].control == HUMAN && worm[3].lives)
{ joyval = ReadJoystick(0);
if (joyval & JOYUP)
yy = -1;
elif (joyval & JOYDOWN)
yy = 1;
if (joyval & JOYLEFT)
xx = -1;
elif (joyval & JOYRIGHT)
xx = 1;
if (joyval & JOYFIRE1)
fire = TRUE;
elif (joyval & JOYFIRE2)
fire = TRUE;
if (joyval != 0)
{ if (fire)
wormqueue(3, 0, 0);
else wormqueue(3, xx, yy);
} } }
void setbrush(SBYTE newbrush)
{ brush = newbrush;
setpointer(brush);
underline(brush);
}
/* Must have blank line at EOF. */